32

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

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

有没有一种特殊的方式我应该删除观察者?或者也许是我应该删除它们的特定位置?

根据这个问题,我做对了,但为什么会收到此错误消息?

这是我的dealloc例程:

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

  }

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

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

4

4 回答 4

46

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

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

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

于 2009-06-13T18:22:48.780 回答
2

你在移除你的观察者[super dealloc] 之前打电话吗?dealloc过早调用 super可能会导致这样的错误。

于 2009-06-13T07:08:53.130 回答
0

你为什么要打电话

[super dealloc]

来自关于 dealloc 的苹果文档

In an implementation of dealloc, do not invoke the superclass’s implementation
于 2014-05-14T15:30:45.953 回答
-11

正常的代码如下所示:

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

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

否则,请编辑您的问题以包括您的 dealloc 重新安排。

于 2009-06-13T09:04:48.683 回答