【问题标题】:Why do I need to remove a notification observer before the object I'm observing is deallocated?为什么我需要在我正在观察的对象被释放之前删除通知观察者?
【发布时间】:2013-01-05 09:59:48
【问题描述】:

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

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

为什么在我正在观察其通知的对象被释放之前停止观察很重要?我理解为什么作为观察者的需要停止观察如果会消失并且阻塞取决于我的存在,但我不明白为什么观察到的物体很重要。我是否误解了这一点?

【问题讨论】:

    标签: cocoa-touch nsnotificationcenter


    【解决方案1】:

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

    我认为可能的解释如下。

    addObserverForName:object:queue:usingBlock 描述说:

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

    在此上下文中的“发送者”只是object 参数的另一个名称,其描述如下:

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

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

    现在,考虑一下:

    1. 观察对象被释放,观察者不被移除;

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 对,但前提是作为观察者消失了。文档似乎建议我需要在我观察到的对象消失之前移除自己,因为它说“addObserverForName:object:queue:usingBlock: 指定的任何对象都被释放”
      • 不,你不需要在你正在观察的对象消失之前移除你自己。这没有任何意义。文档只影响被标记为观察者的对象。
      • 那么,它在说什么对象呢?此方法注册一个块来观察通知,而不是对象 + 选择器。该块已经保留了它所拥有的任何东西。
      猜你喜欢
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      相关资源
      最近更新 更多