0Pricing
Swift Academy · Урок

Альтернативы шаблону наблюдателя

Сравнивайте его с делегатами и издателями 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 — локальная установка не требуется.

Все уроки этого курса

  1. Публикация и наблюдение за уведомлениями
  2. Полезные данные уведомлений userInfo
  3. Безопасное удаление наблюдателей
  4. Альтернативы шаблону наблюдателя
← Назад к Swift Academy