Возможные места для вызова методов addObserver и removeObserver - PullRequest
8 голосов
/ 01 января 2009

У меня есть случай, когда дочернее представление отправляет уведомление родительскому представлению. Теперь я звоню 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];

Спасибо.

Ответы [ 3 ]

5 голосов
/ 01 января 2009

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

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

1 голос
/ 01 января 2009

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

0 голосов
/ 03 марта 2012

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

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

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

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

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

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

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

...