Какой лучший способ удалить наблюдателя уведомлений
Я обычно использую 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). Это следует за предложением моих друзей.
Я хочу знать, прав ли мой друг или нет? На мой взгляд, поскольку текущий экземпляр будет выгружен или dealloc, уведомление суперкласса также бесполезно. И есть ли уведомление об использовании подкласса системы UIViewController?
Ответы
Ответ 1
Ваш друг на 100% прав. Хотя, не имеет значения, удалите ли вы все уведомления в dealloc.
Вы упомянули viewDidUnload
, и там дело совершенно другое, потому что незагруженный объект останется в живых, и вы не знаете, когда добавляются замечания по надзору над суперклассом. Если они добавлены в viewDidLoad, у вас не будет проблем. Если они добавлены в методе init, вы просто потеряли кучу важных уведомлений.
Удаление наблюдений с конкретными именами является хорошей практикой и должно выполняться с самого начала.
Ответ 2
Если вы хотите удалить все уведомления, которые используете,
[[NSNotificationCenter defaultCenter] removeObserver:self];
Если вы хотите удалить определенное уведомление, которое вы используете,
[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];
Когда вы больше не нуждаетесь в каком-либо уведомлении, первый подход прост.
Ответ 3
Как объект уходит, безопасно использовать [[NSNotificationCenter defaultCenter] removeObserver:self];
в методе dealloc
.
В методе ViewDidUnload
вам лучше удалить каждого наблюдателя один за другим, так как ссылка на контроллер все еще рядом (и ваш соответствующий viewDidLoad
должен добавить их обратно).
Ответ 4
Я использую первый способ, я никогда не думал о том, было ли это правильно или нет. Если вызывается dealloc, тогда объект (супер также) будет все равно освобожден. То, что вы определенно НЕ хотите, это NSNotification, отправляемый на освобожденный экземпляр.