16

我通常像下面的示例一样使用 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 子类使用通知?

4

4 回答 4

12

你的朋友是 100% 正确的。不过,是否删除 dealloc 中的所有通知观察并不重要。
您提到viewDidUnload了,情况完全不同,因为卸载的对象将保持活动状态,并且您不知道何时再次添加超类的通知观察。如果将它们添加到 viewDidLoad 中,则不会有问题。如果将它们添加到 init 方法中,您只会丢失一堆重要的通知观察。

删除具有特定名称的观察是一种很好的做法,应该从一开始就完成。

于 2012-04-06T09:12:13.363 回答
8

当您想删除您使用的所有通知时,

[[NSNotificationCenter defaultCenter] removeObserver:self];

如果您想删除您使用的特定通知,

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

当您不再需要任何通知时,第一种方法很简单。

于 2012-04-06T06:19:31.300 回答
1

随着对象消失,[[NSNotificationCenter defaultCenter] removeObserver:self];dealloc方法中使用它是安全的。

ViewDidUnload方法中,您最好一个一个地删除每个观察者,因为对控制器的引用仍然存在(并且您的对应viewDidLoad应该将它们全部添加回来)。

于 2012-04-07T14:03:55.340 回答
0

我用的是第一种方式,从来没想过对不对。如果调用了 dealloc,那么无论如何都会释放对象(超级对象)。您绝对不想要的是将 NSNotification 发送到已释放的实例。

于 2012-04-06T06:20:50.897 回答