Какой лучший способ удалить Notification observer

Я обычно использую NSNotification как образец ниже:

в viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bar:) name:kName2 object:nil];

в viewDidUnload и dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self];

но друг сказал мне, что я не должен использовать [[NSNotificationCenter defaultCenter] removeObserver:self]; потому что он удалит всех наблюдателей, включая супер-класс . Он предложил мне использовать следующий код для удаления наблюдателя один за другим.

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kName2 object:nil];

Я проверил код библиотеки ASIHttpRequest ( https://github.com/pokeb/asi-http-request ). Это следует совету моих друзей.

Я хочу знать, прав мой друг или нет? На мой взгляд, поскольку текущий экземпляр будет выгружаться или освобождаться, уведомление суперкласса также бесполезно. И есть ли в системе UIViewController подкласс use notification?

4 ответов


ваш друг на 100% прав. Хотя, это не имеет значения, если вы удалите все наблюдения уведомлений в dealloc.
Вы упомянули viewDidUnload, и там случай совершенно другой, потому что выгруженный объект останется в живых, и вы не знаете, когда наблюдения уведомлений суперкласса будут добавлены снова. Если они будут добавлены в viewDidLoad, у вас не будет проблем. Если они добавляются в метод init, вы просто потеряли кучу важных наблюдений уведомлений.

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


когда вы хотите удалить все уведомления, которые вы используете,

[[NSNotificationCenter defaultCenter] removeObserver:self];

Если вы хотите удалить конкретное уведомление, которое вы используете,

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];

когда вы больше не нуждаетесь в каком-либо уведомлении, первый подход прост.


как объект уходит, это безопасно использовать [[NSNotificationCenter defaultCenter] removeObserver:self]; на dealloc метод.

на ViewDidUnload метод, вам лучше удалить каждого наблюдателя по одному, поскольку ссылка на контроллер все еще вокруг (и ваш соответствующий viewDidLoad должен добавить их все обратно).


Я использую первый способ, я никогда не думал о том, правильно это или нет. Если вызывается dealloc, то объект (супер также) будет освобожден в любом случае. То, что вы определенно не хотите, - это отправка NSNotification в освобожденный экземпляр.