【问题标题】:When should I remove observers? Error about deallocating objects before removing observers我应该什么时候移除观察者?在移除观察者之前释放对象的错误
【发布时间】:2010-11-02 16:02:40
【问题描述】:

我正在尝试在我的一门课程中使用键值观察。我在 init 方法中注册观察者并在 dealloc 中删除/取消注册它们,但是根据我的调试打印,我得到了以下错误,这似乎发生在我的 dealloc 方法被调用之前。

TekkPoint 类的实例 0x583870 正在被释放,而键值观察者仍向其注册。观察信息被泄露,甚至可能被错误地附加到其他对象上。在 NSKVODeallocateBreak 上设置断点以在调试器中停止。这是当前的观察信息: ( 上下文:0x0,属性:0x536400> 上下文:0x0,属性:0x55aba0> )

我有什么特别的方法可以移除观察者吗?或者我应该删除它们的特定位置?

根据这个question,我做对了,但是为什么我会收到这个错误信息?

这是我的 dealloc 例程:

- (void)dealloc {
  // Remove all observers.
  for (NSString *path in [TekkPoint observedPaths]) {
    [self removeObserver:[option_ tChart]
          forKeyPath:path];

  }

  [description_ release];
  [weight_ release];
  [super dealloc];
}

需要注意的一点是,我的实现可能很奇怪,我正在从被观察者中添加和删除观察者,这会导致我的问题吗?

【问题讨论】:

    标签: objective-c cocoa-bindings observer-pattern key-value-observing


    【解决方案1】:

    啊。您正在从SomethingElse 对象观察TekkPoint 对象,而SomethingElse 对象是添加和删除观察者的对象,对吗? (这是正常的处理方式;我只是想澄清一下。)

    看起来您的 TekkPoint 对象正在被释放,而正在观察它的 SomethingElse 仍然存在。未调用 SomethingElse dealloc 方法,因为正在释放的是 TekkPoint,而不是 SomethingElse

    如果您计划观察一个可能在观察者消失之前消失的对象,那么您需要某种方式来通知观察者他们应该移除他们的观察者。你的TekkPoint 可以有一个alive 属性,SomethingElse 也可以观察到它,当它设置为NO 时,观察TekkPoint 的每个人都会将自己作为观察者移除。

    【讨论】:

    • 另一种选择是在观察它的对象中创建对被观察对象的强引用。这样在观察者也被释放之前,被观察的对象不会被释放。
    【解决方案2】:

    您是否在移除观察者之前调用[super dealloc]?过早调用 super 的 dealloc 可能会导致这样的错误。

    【讨论】:

    • 不,我绝对有顺序。 [super dealloc] 是我在 dealloc 中调用的最后一件事。
    • 旧线程,但刚刚遇到它。是的,super dealloc 绝对应该是最后一个。
    【解决方案3】:

    你为什么要打电话

    [super dealloc]
    

    来自关于 dealloc 的苹果文档

    In an implementation of dealloc, do not invoke the superclass’s implementation
    

    【讨论】:

    【解决方案4】:

    正常的代码如下所示:

    - (void) dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [super dealloc];
    }
    

    仔细检查你的 dealloc 方法的签名(Objective C 是非常无情的,当你弄乱方法的名称时永远不会警告你)。例如,如果您的方法名称是“dealoc”(带有一个 l),那么您的 dealloc 将永远不会被调用。

    否则,请编辑您的问题以包含您的 dealloc 程序。

    【讨论】:

    • 与键值观察无关。
    • 这个问题是针对 KVO 而不是通知
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 2012-07-17
    相关资源
    最近更新 更多