Альтернативы шаблону наблюдателя
Сравнивайте его с делегатами и издателями Combine.
«Альтернативы шаблону наблюдателя» — бесплатный урок Swift Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Альтернативы шаблону наблюдателя
NotificationCenter — один из способов реагировать на события. Swift предлагает и другие: делегирование, Combine и асинхронные последовательности. Каждый вариант подходит для своей формы взаимодействия.
Шаблон наблюдателя
Шаблон наблюдателя позволяет объектам подписываться на события субъекта. NotificationCenter — это глобальная реализация этого шаблона со слабо связанными компонентами.
import Foundation
// Subject posts, observers react, neither holds the other.
NotificationCenter.default.post(name: Notification.Name("tick"), object: nil)
print("Broadcast an event")Делегирование
delegate — это связь один к одному: объект передаёт определённые события одному delegate через протокол. Такой подход явный и типобезопасный.
protocol DownloadDelegate: AnyObject {
func didFinish(_ bytes: Int)
}
class Downloader {
weak var delegate: DownloadDelegate?
func finish() { delegate?.didFinish(1024) }
}
print("Delegate is one-to-one and typed")Delegate и уведомления
Используйте delegate, когда событие важно ровно одному объекту и связь между ними очевидна. Используйте NotificationCenter, когда реагировать могут многие неизвестные заранее наблюдатели.
import Foundation
// One listener -> delegate. Many/unknown listeners -> NotificationCenter.
print("Cardinality guides the choice")Издатели Combine
Combine представляет события как издателей, на которых можно подписаться с помощью sink, поддерживая операторы преобразования, например map и filter.
import Combine
let subject = PassthroughSubject<Int, Never>()
let c = subject.sink { print("Got \($0)") }
subject.send(5)
_ = cИздатель NotificationCenter
Combine связывает NotificationCenter с этой моделью: publisher(for:) превращает уведомления в поток, который можно преобразовывать.
import Foundation
import Combine
let name = Notification.Name("ping")
let c = NotificationCenter.default.publisher(for: name)
.sink { _ in print("Combine got notification") }
NotificationCenter.default.post(name: name, object: nil)
_ = cОператоры Combine
Сильная сторона Combine — композиция конвейеров событий: декларативная фильтрация, устранение дребезга, объединение и преобразование значений.
import Combine
let subject = PassthroughSubject<Int, Never>()
let c = subject
.filter { $0 > 0 }
.map { $0 * 2 }
.sink { print($0) }
subject.send(-1)
subject.send(3)
_ = cАсинхронные последовательности
Современный Swift предлагает AsyncStream и асинхронные последовательности уведомлений, позволяя получать события с помощью for await в структурированной конкурентности.
import Foundation
func listen() async {
let name = Notification.Name("ping")
for await _ in NotificationCenter.default.notifications(named: name) {
print("Async observed")
break
}
}
print("Can await notifications")Замыкания и обратные вызовы
Для одного локального обратного вызова проще всего сохранить замыкание — без какой-либо инфраструктуры наблюдателей.
struct Button {
var onTap: () -> Void
func tap() { onTap() }
}
Button(onTap: { print("tapped") }).tap()Выбор подхода
Делегат: один к одному, явная связь. NotificationCenter: многие ко многим, независимые компоненты. Combine и асинхронные последовательности: потоки, требующие преобразования. Замыкание: простые локальные обратные вызовы.
import Foundation
// Match the tool to the communication shape.
print("Delegate, Notification, Combine, async, closure")Компромиссы
NotificationCenter гибок, но не типобезопасен, и с ним легко допустить утечку памяти. Делегирование и Combine типобезопасны; Combine и асинхронные последовательности дают больше возможностей ценой появления дополнительных понятий.
import Foundation
// Prefer typed approaches when the relationship is known.
print("Type safety vs flexibility tradeoff")Быстрая проверка
Какой механизм лучше всего подходит для понятной типобезопасной связи один к одному?
Повторение
В Swift шаблон наблюдателя представлен в нескольких формах: NotificationCenter для независимых событий по схеме «многие ко многим», делегирование для типизированных связей один к одному, Combine и асинхронные последовательности для компонуемых потоков и замыкания для простых обратных вызовов. Выбирайте подход с учётом формы взаимодействия и требований к типобезопасности. На этом курс завершён.
Часто задаваемые вопросы
Урок «Альтернативы шаблону наблюдателя» бесплатный?
Да — полный текст урока «Альтернативы шаблону наблюдателя» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Альтернативы шаблону наблюдателя»?
Сравнивайте его с делегатами и издателями Combine. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Альтернативы шаблону наблюдателя»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Публикация и наблюдение за уведомлениями
- Полезные данные уведомлений userInfo
- Безопасное удаление наблюдателей
- Альтернативы шаблону наблюдателя