简体   繁体   English

哪个是删除 Notification observer 的更好方法

[英]Which is a better way to remove Notification observer

I usually use NSNotification like the sample below:我通常像下面的示例一样使用 NSNotification:

In viewDidLoad:在 viewDidLoad 中:

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

In viewDidUnload and dealloc:在 viewDidUnload 和 dealloc 中:

[[NSNotificationCenter defaultCenter] removeObserver:self];

But a friend told me that I should not use [[NSNotificationCenter defaultCenter] removeObserver:self];但是一个朋友告诉我,我不应该使用[[NSNotificationCenter defaultCenter] removeObserver:self]; because it will remove all the observers including the super class's.因为它将删除所有观察者,包括超类的观察者。 He suggested me to use the following code to remove observer one by one.他建议我使用下面的代码来一个一个地移除观察者。

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

I've checked the ASIHttpRequest library's code ( https://github.com/pokeb/asi-http-request ).我检查了 ASIHttpRequest 库的代码( https://github.com/pokeb/asi-http-request )。 It follows my friends' suggestion.它遵循我朋友的建议。

I want to know if my friend is right or not?我想知道我朋友说的对不对? In my opinion, since the current instance will be unload or dealloc, the super class's notification is also useless.在我看来,既然当前实例会被unload或dealloc,超类的通知也是无用的。 And is there any system UIViewController subclass use notification?还有系统UIViewController子类使用通知吗?

Your friend is 100% correct.你的朋友是 100% 正确的。 Though, it does not matter if you remove all notification observations in dealloc.但是,删除 dealloc 中的所有通知观察并不重要。
You mentioned viewDidUnload , and there the case is completely different, because the unloaded object will stay alive, and you don't know when the notification observations of the superclass are added again.你提到了viewDidUnload ,那里的情况完全不同,因为卸载的 object 将保持活着,你不知道什么时候再次添加超类的通知观察。 If they are added in viewDidLoad you won't have a problem.如果将它们添加到 viewDidLoad 中,则不会有问题。 If they are added in an init method you just lost a bunch of important notification observations.如果将它们添加到 init 方法中,您就会丢失一堆重要的通知观察结果。

Removing observations with specific names is good practice and should be done from the beginning.删除具有特定名称的观察是一种很好的做法,应该从一开始就完成。

When you want to remove all notification you use,当你想删除你使用的所有通知时,

[[NSNotificationCenter defaultCenter] removeObserver:self];

If you want to remove a particular notification you use,如果你想删除你使用的特定通知,

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

When you no longer in need of any notification the first approach is simple.当您不再需要任何通知时,第一种方法很简单。

As the object is going away, it's safe to use [[NSNotificationCenter defaultCenter] removeObserver:self];由于 object 即将消失,因此可以安全地使用[[NSNotificationCenter defaultCenter] removeObserver:self]; in the dealloc method.dealloc方法中。

In ViewDidUnload method, you'd better remove each observer one by one as a reference to the controller is still around (and your corresponding viewDidLoad should add them all back in).ViewDidUnload方法中,你最好一个一个地删除每个观察者,因为对 controller 的引用仍然存在(你相应的viewDidLoad应该将它们全部添加回来)。

I use the first way, I never thought about whether it was right or not.我用的是第一种方式,从来没想过对不对。 If dealloc is being called, then the object (super as well) is going to be deallocated anyway.如果调用 dealloc,那么 object(也包括 super)无论如何都会被释放。 What you definitely DON'T want is the NSNotification being sent to a deallocated instance.您绝对不希望将 NSNotification 发送到已释放的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM