2014-08-25 3 views
2

Я не могу найти окончательного ответа на эту тему.Удалить наблюдателя NSNotification, который может не существовать

Можно ли удалить наблюдателя, который может не существовать?

Пример кода:

-(void)commonInit{ 

    [[NSNotificationCenter defaultCenter]removeObserver:self]; 


    [[NSNotificationCenter defaultCenter]addObserver:self 
             selector:@selector(userDidChangePrecision:) 
              name:kUser_Changed_Precision 
              object:nil]; 

} 


-(void)dealloc{ 

    [[NSNotificationCenter defaultCenter]removeObserver:self]; 

    [super dealloc]; 

} 

Это предотвратить бы больше, чем один наблюдатель инициализации для объекта в том случае, когда объект может быть инициализируется во время выполнения.

+0

Кажется странным назвать * commonInit * более одного раза? – nielsbot

ответ

3

Отрывок из документации Apple:

- (void)removeObserver:(id)notificationObserver 
    Parameters 
    *notificationObserver* 
     The observer to remove. Must not be nil. 

- (void)removeObserver:(id)notificationObserver name:(NSString *)notificationName object:(id)notificationSender 
    Parameters 
    *notificationObserver* 
     Observer to remove from the dispatch table. Specify an observer to remove only entries for this observer. Must not be nil, or message will have no effect. 

В обоих случаях предупреждение, что наблюдатель не может быть нулевым завышена; эффект в обоих случаях заключается в том, что это сообщение не имеет эффекта. Ни компилятор, ни ошибки времени выполнения, ни зомби, & c.

Аналогично, указание наблюдателя, которое не соблюдается, также не имеет никакого эффекта.

не окончательный ответ, но на основе наблюдений и исследований, играя с кодом проб и ошибок, таких как:

[[NSNotificationCenter defaultCenter] removeObserver:nil]; [[NSNotificationCenter defaultCenter] removeObserver:[UIView new]];

+1

Я полагаю, что теоретически это предположение может вернуться, чтобы укусить вас позже ... – nielsbot

+1

Вы можете добавить флаг к своему потенциальному наблюдателю * isObserving * .. Это можно добавить через категорию + * objc_ [set | get] AssociatedObject * if это не класс, определенный в вашем коде. – nielsbot

+0

@nielsbot, это довольно аккуратно. – Thompson

3

Я не могу найти исчерпывающую документацию по, если это разрешено удалить несуществующих наблюдателей, но я думаю, что документация NSNotificationCenter может быть прочитана таким образом. В нем говорится, что removeObserver:name:object: удаляет соответствует наблюдателей. Я просто предполагаю, что это включает no соответствующих наблюдателей.

Но вот еще одна причина, по которой ваш подход может быть вреден: когда ваш метод commonInit вызывается другим кодом (инициализация под- или суперклассами), возможно, уже зарегистрирован для уведомлений. При подклассификации UIViewController это даже вероятно (для предупреждений о памяти).

Поэтому я бы сказал, что вы никогда не должны безоговорочно отменять регистрацию из центра уведомлений, за исключением dealloc.

Смежные вопросы