В каких методах жизненного цикла UIViewController лучше подписываться и отписываться от NotificationCenter?

«В каких методах жизненного цикла UIViewController лучше подписываться и отписываться от NotificationCenter?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Стратегия зависит от необходимости уведомлений:

1. Подписка на постоянные уведомления (нужны, пока контроллер жив)

  • Подписка: viewDidLoad()
  • Отписка: deinit
// viewDidLoad
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleDataUpdate),
        name: .dataDidUpdateNotification,
        object: nil
    )
}

// deinit
deinit {
    // Обязательная отписка для предотвращения утечек памяти
    NotificationCenter.default.removeObserver(self)
}

2. Подписка на временные уведомления (нужны только когда экран видим)

  • Подписка: viewWillAppear(_:)
  • Отписка: viewWillDisappear(_:)
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleAppBecameActive),
        name: UIApplication.didBecomeActiveNotification,
        object: nil
    )
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
}

Best Practices:

  • Всегда отписывайтесь. Неотписанный наблюдатель удерживает контроллер в памяти.
  • В iOS 9+ и с использованием блоков отписываться явно не нужно, если использовать возвращаемый токен и хранить его в свойстве (он автоматически отпишется при деинициализации).
  • Для отписки от конкретного уведомления используйте removeObserver(_:name:object:) — это точнее, чем removeObserver(_:).