Всем привет! С выходом
iOS 26 работа с уведомлениями в
Swift Concurrency кардинально меняется. Старый добрый
NotificationCenter, который годами служил верой и правдой, теперь выглядит как отголосок из прошлого - он не понимает модель акторов и постоянно генерирует предупреждения компилятора, но у
Apple готово элегантное решение: протоколы
MainActorMessage и
AsyncMessage. Давайте разберемся, как они работают и почему это настоящий прорыв.
Проблемы старого подхода:
Традиционный
NotificationCenter сталкивается с двумя фундаментальными проблемами в
Swift Concurrency:
- Нарушение изоляции акторов: даже при подписке на главной очереди компилятор видит потенциальную гонку данных при вызове методов, помеченных @MainActor
- Отсутствие типобезопасности: постоянные приведения типов через as? создают хрупкий код, где ошибки обнаруживаются только в рантайме
MainActorMessage - гарантия выполнения на главном потоке:
Новый протокол решает первую проблему кардинально - он явно указывает, что уведомление должно обрабатываться на главном акторе. Посмотрим на разницу:
// Старый подход
NotificationCenter.default.addObserver(
forName: UIApplication.didBecomeActiveNotification,
object: nil,
queue: .main,
using: { [weak self] _ in
self?.updateUI() // Warning: Call to main actor-isolated method
}
)
// Новый подход
private var observationToken: NotificationCenter.ObservationToken?
// Подписываемся и сохраняем token
observationToken = NotificationCenter.default.addObserver(
of: UIApplication.self,
for: .didBecomeActive
) { [weak self] message in
self?.updateUI() // Без предупреждений
}
// Отмена подписки
deinit {
observationToken?.cancel()
}
AsyncMessage: гибкость для фоновых задач:
Для сценариев, где не требуется главный поток, идеально подходит
AsyncMessage. Он доставляет уведомления асинхронно, сохраняя при этом строгую типизацию:
struct DataSyncMessage: NotificationCenter.AsyncMessage {
typealias Subject = SyncResult
let result: Subject
}
// Отправка из любого контекста
let message = DataSyncMessage(result: syncResult)
NotificationCenter.default.post(message)
Вывод:
Внедрение
MainActorMessage и
AsyncMessage - это не просто следование трендам, а повышение качества кода. Мы получаем не только технические преимущества в виде компиляторных проверок и строгой типизации, но и совершенно иной уровень уверенности в своем коде.