【问题标题】:Do I have to removeObserver in KVO manually我是否必须手动删除 KVO 中的观察者
【发布时间】:2013-10-22 09:50:18
【问题描述】:

我已经阅读了关于 KVO 的 apple document,它说:

注意:key-value 观察 addObserver:forKeyPath:options:context: 方法不维护对观察对象的强引用, 观察到的对象,或上下文。你应该确保你 保持对观察对象和观察对象的强烈引用, 以及必要的上下文。

观察者对象没有对被观察对象的强引用。

这个人我不能在dealloc 方法中调用removeObserver:forKeyPath: 吗?可以自动移除观察者吗?

【问题讨论】:

    标签: ios objective-c key-value-observing


    【解决方案1】:

    您必须手动致电-removeObserver:forKeyPath:。 iOS 不会自动执行此操作。

    苹果说does not maintain strong references to the observing object。我认为这意味着,如果你想从临时变量的范围内删除临时变量的观察者,你应该将临时变量设为 ivar,这样你就可以维护 ivar 的强引用。

    如果您不致电-removeObserver:forKeyPath:。你会做:1)有东西泄漏

    比如你的代码是这样的:

    [self addObserver:a forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    

    如果您不致电-removeObserver:forKeyPath:。它会安慰:

    An instance 0x756a1d0 of class MyClass was deallocated while key value observers were still registered with it. Observation info was
    

    泄漏,甚至可能被错误地附着在其他物体上。 在 NSKVODeallocateBreak 上设置断点以在调试器中停止。 这是当前的观察信息: [NSKeyValueObservationInfo 0x7574f60] ( [NSKeyValueObservance 0x7574f20:观察者:0x7568280,密钥路径:pageCount,选项:[新:是,旧:否,先前:否] 上下文:0x0, 属性:0x7574fa0] )

    当你调试它时,你会发现:selfa 没有泄漏。泄漏的东西是NSKeyValueObservationInfo object

    如果您不致电-removeObserver:forKeyPath:。您将: 2) 中级类永远不会破坏 && Infinity 通知

    正如苹果关于 KVO 的文档所说:

    当一个观察者注册一个对象的属性时,is 被观察对象的指针被修改,指向一个 中间类而不是真正的类。

    removeObserver 时,如果没有注册观察者,中间类会销毁。并且如果你不调用removeObserver,中间类永远不会销毁,当你改变属性时,中间类的setter方法会继续发送通知。

    【讨论】:

    • 谢谢。我幸运地偶然发现了我的无限通知问题,这澄清了发生了什么。我希望 KVO 只是让被观察的对象释放并自动停止观察。
    【解决方案2】:

    removeObserver:forKeyPath: 与内存管理或维护引用无关。它只是告诉运行时您的对象不再需要被通知该 keyPath 上对象的更改。

    【讨论】:

      【解决方案3】:

      不,您必须在不再需要 -removerObserver:forKeyPath: 时调用它,否则 KVO 系统将有一些悬空指针可能会泄漏或附加到另一个意外的对象上。

      【讨论】:

        【解决方案4】:

        不,你必须调用它。

        不强并不总是弱

        但在这种情况下,它意味着 unsafe_unretained。

        如果您不删除观察者,您会收到一条错误消息:“对象 XY 已被释放,而仍有观察者”

        它可能会崩溃

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多