Возможные места для вызова методов addObserver и removeObserver

StackOverflow https://stackoverflow.com/questions/404522

Вопрос

У меня есть случай, когда дочернее представление отправляет уведомление своему родительскому представлению.Теперь я звоню addObserver: в viewWillAppear: и removeObserver: в viewWillDisappear:.Но, я предполагаю, что это неверно, поскольку viewWillAppear: вызывает при обновлении представления.

[[NSNotificationCenter defaultCenter] addObserver: (id)observer selector: (SEL)aSelector name: (NSString *)aName object: (id)anObject];

[[NSNotificationCenter defaultCenter] removeObserver: (id)observer name: (NSString *)aName object: (id)anObject];

Спасибо.

Это было полезно?

Решение

На самом деле, это плохая идея.Когда памяти становится мало, вашему контроллеру просмотра может быть отправлено предупреждение о нехватке памяти.Поведение по умолчанию в этом случае заключается в очистке вашего представления (если вы в данный момент не находитесь на экране).В этом случае вы могли бы получить сообщение viewDidLoad, отправленное во второй раз (после события memory, когда ваш вид возвращается на экран с помощью навигационного контроллера). Таким образом, у вас будет две регистрации одного и того же объекта, но только одно удаление (в его dealloc)

Лучшим решением является либо установка флага, говорящего о том, что вы зарегистрировались, либо регистрация в вашем методе инициализации.

Другие советы

Я предполагаю, что правильными позициями для регистрации для получения уведомления являются viewDidLoad метод и правильная позиция для отмены регистрации для тех же уведомлений следующие dealloc способ.

Бен прав, но я нашел другой, потенциально хрупкий, способ обойти это.Я только что обнаружил это, потому что я постоянно получал сообщение "... был освобожден, в то время как наблюдатели за ключевыми значениями все еще были зарегистрированы с ним".

Я не знаю почему, но когда у меня был addObserver в моем методе init и removeObserver в моем методе dealloc, я все еще получал сообщение о том, что KVO все еще наблюдается.Я прошел через это и убедился, что мой removeObserver вызывается правильно.

Вместо этого я переместил свой addobserver в метод viewDidLoad, и это, похоже, сработало.

Я оставил removeObserver в viewDidUnload и в dealloc;но мне это не нравится, потому что это не сбалансировано.Но при обычных обстоятельствах мой viewDidUnload не вызывается - это просто защита на случай, если я получу уведомление о нехватке памяти.

Но я вижу, что потенциально могу попасть в ситуацию, когда возникает событие нехватки памяти, вызывается viewDidUnload.Если я затем нажму dealloc через некоторое время после этого (прежде чем снова нажму viewDidLoad), я дважды вызову removeObserver!

Так что, я думаю, я просто сохраню это в моем viewDidLoad и моем dealloc.

Я до сих пор не знаю, почему это не работает правильно, если я использую addobserver в своем методе init.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top