← Назад к вопросам

Какие знаешь методы у Observer?

2.0 Middle🔥 172 комментариев
#Архитектура и паттерны

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Методы паттерна Observer и его реализация в iOS

В паттерне Наблюдатель (Observer) ключевыми методами являются методы подписки, отписки и оповещения. В iOS этот паттерн реализован несколькими способами, каждый со своими специфическими методами.

Базовые методы классического Observer

В классической реализации паттерна обычно присутствуют:

  • subscribe() / addObserver() – добавление наблюдателя к субъекту
  • unsubscribe() / removeObserver() – удаление наблюдателя
  • notify() / update() – оповещение всех наблюдателей об изменении состояния
  • В некоторых реализациях также используется getState() для получения текущего состояния субъекта

Реализации Observer в iOS

1. NotificationCenter (Центр уведомлений)

// Метод добавления наблюдателя
NotificationCenter.default.addObserver(
    self,
    selector: #selector(handleNotification(_:)),
    name: NSNotification.Name("DataUpdated"),
    object: nil
)

// Метод отправки уведомления
NotificationCenter.default.post(
    name: NSNotification.Name("DataUpdated"),
    object: self,
    userInfo: ["newData": updatedData]
)

// Метод удаления наблюдателя
NotificationCenter.default.removeObserver(self)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name("DataUpdated"), object: nil)

// Обработчик уведомления
@objc func handleNotification(_ notification: Notification) {
    if let data = notification.userInfo?["newData"] as? MyDataType {
        // Обработка данных
    }
}

2. Key-Value Observing (KVO)

KVO использует другой подход, основанный на ключевых путях:

// Добавление наблюдателя
objectToObserve.addObserver(
    self,
    forKeyPath: #keyPath(MyClass.importantProperty),
    options: [.new, .old],
    context: nil
)

// Обработка изменений
override func observeValue(
    forKeyPath keyPath: String?,
    of object: Any?,
    change: [NSKeyValueChangeKey : Any]?,
    context: UnsafeMutableRawPointer?
) {
    if keyPath == #keyPath(MyClass.importantProperty) {
        let oldValue = change?[.oldKey] as? String
        let newValue = change?[.newKey] as? String
        // Обработка изменения
    }
}

// Удаление наблюдателя
objectToObserve.removeObserver(self, forKeyPath: #keyPath(MyClass.importantProperty))

3. Combine Framework (современный подход)

В современном Swift используется фреймворк Combine:

// Создание субъекта (Publisher)
private let dataSubject = PassthroughSubject<MyData, Never>()

// Подписка на изменения
var cancellables = Set<AnyCancellable>()

func setupObserver() {
    dataSubject
        .sink { [weak self] newData in
            self?.updateUI(with: newData)
        }
        .store(in: &cancellables)
}

// Отправка обновлений
func updateData(_ newData: MyData) {
    dataSubject.send(newData)
}

// Автоматическая отписка при деинициализации
// (хранится в cancellables)

4. Делегирование (Delegation)

Хотя делегирование не является pure Observer, оно часто используется для аналогичных целей:

protocol DataUpdateDelegate: AnyObject {
    func dataDidUpdate(_ newData: MyData)
}

// Метод установки делегата
weak var delegate: DataUpdateDelegate?

// Вызов метода делегата при изменении
private func notifyDelegate() {
    delegate?.dataDidUpdate(currentData)
}

Сравнение методов

NotificationCenter:

  • Плюсы: Глобальная доступность, простота использования, поддержка множества наблюдателей
  • Минусы: Строковые идентификаторы (риск опечаток), необходимость ручной отписки

KVO:

  • Плюсы: Автоматическое наблюдение за свойствами, интеграция с Objective-C runtime
  • Минусы: Громоздкий синтаксис, необходимость наследования от NSObject, сложность отладки

Combine:

  • Плюсы: Типобезопасность, композиция операторов, автоматическое управление памятью
  • Минусы: Требует iOS 13+, кривая обучения

Рекомендации по выбору метода

  1. Для простых межмодульных уведомлений – используйте NotificationCenter
  2. Для реактивного программирования – выбирайте Combine (для iOS 13+)
  3. Для наблюдения за свойствами объектов – в новых проектах избегайте KVO, используйте Combine или Property Observers
  4. Для связи между близко связанными объектами – рассмотрите делегирование

Важные особенности реализации

Все методы Observer в iOS требуют внимания к управлению памятью:

  • Использование weak ссылок для делегатов
  • Своевременная отписка в deinit
  • Использование [weak self] в замыканиях

Типичная ошибка новичков – забывать отписываться от наблюдений, что приводит к утечкам памяти и крашам при обращении к освобожденным объектам.

Каждый метод Observer в iOS имеет свою нишу применения, и опытный разработчик должен владеть всеми ими, выбирая наиболее подходящий для конкретной задачи с учетом требований проекта, версии iOS и архитектурных предпочтений.

Какие знаешь методы у Observer? | PrepBro