Удаляет ли NSNotificationCenterObserver: отменяет регистрацию VC от получения уведомлений о предупреждении памяти?
Я просто наткнулся на проблему в своем приложении: я протестировал вызовы didReceiveMemoryWarning
на UIViewController
, включая последующие вызовы для viewDidUnload
.
Это хорошо работало в старых версиях моего приложения, но теперь не работало в iPhone Simulator:
didReceiveMemoryWarning
больше не вызывался.
Это вызвано вызовом [NSNotificationCenter defaultCenter] removeObserver:self]
в viewWillDisappear
(сам являющийся UIViewController), чтобы отменить регистрацию для некоторых уведомлений о жизненном цикле, которые я добавил в viewDidAppear
.
Этот глобальный вызов removeObserver:
не только удалил мои добавленные уведомления, но, видимо, также уведомление системы UIApplicationDidReceiveMemoryWarningNotification вызвало вызов UIViewController didReceiveMemoryWarning
.
Это поведение по дизайну? Я не мог найти ссылку/документ, который указывал, что вызов removeObserver:
внутри UIViewController нарушает стандартную обработку памяти.
Ответы
Ответ 1
Да, это по дизайну.
Такое поведение меня совсем не удивляет. Реализация UIViewController непрозрачна, поэтому нет возможности точно знать, что она регистрирует экземпляры для UIApplicationDidReceiveMemoryWarningNotification
с помощью действия didReceiveMemoryWarning
, но это, безусловно, имеет смысл.
Как правило, это плохая практика использовать [[NSNotificationCenter defaultCenter] removeObserver:self]
где угодно, но в dealloc
. Это связано с тем, что, как вы обнаружили, могут быть непредсказуемые побочные эффекты в реализациях суперкласса. Это более предсказуемо и проще отлаживать/поддерживать ваш код, если вы следуете за соглашением о регистрации только для определенных уведомлений, которые вы зарегистрировали.
Ответ 2
[NSNotificationCenter defaultCenter] removeObserver:observer]
отменяет регистрацию observer
для всех уведомлений, для которых она ранее была зарегистрирована (включая системные уведомления).
Вы можете использовать метод removeObserver:name:object:
для отмены подписки на одно уведомление.