3

来自https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

您必须在 addObserverForName:object:queue:usingBlock: 指定的任何对象被释放之前调用 removeObserver: 或 removeObserver:name:object:

为什么在我正在观察其通知的对象被释放之前停止观察很重要?我理解为什么作为观察者需要停止观察,如果要消失并且块取决于我的存在,但我不明白为什么被观察对象的生命周期很重要。我误解了这个吗?

4

2 回答 2

6

我理解为什么我作为观察者需要停止观察,如果我要消失并且块取决于我的存在,但我不明白为什么被观察对象的生命周期很重要。

我认为可能的解释如下。

addObserverForName:object:queue:usingBlock描述 说:

向接收者的调度表添加一个条目,其中包含一个通知队列和一个要添加到队列的块,以及可选条件:通知名称和发送者。

在这种情况下,“sender”只是object参数的另一个名称,在以下术语中进行了描述:

要将块添加到操作队列的通知的对象。如果你传递 nil,通知中心不会使用通知的发送者来决定是否将块添加到操作队列中。

因此,object充当一种过滤器:当通知进入时,通知中心根据该值(如果存在)决定是否必须将块添加到指定的操作队列。

现在,考虑一下:

  1. 被观察对象在没有观察者被移除的情况下被释放;

  2. 创建了一个不同的对象,也能够发布通知,并且它恰好与在点 1 处释放的对象具有相同的地址;

  3. 现在观察者将对第二个对象发布的通知做出反应。

我承认这是一个非常罕见的情况,但它可能会发生,所以你最好针对它编写代码。

于 2013-01-05T10:21:56.627 回答
-1

如果您不删除观察者,则可能会导致您已经销毁对象但仍会发送通知的情况-这将导致“消息发送到已释放实例”错误

于 2013-01-05T10:03:34.333 回答