32

我想在我的一个类中使用键值观察。我在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]; 
} 

有一点要注意,可能会奇怪我的实现是我加入,并从observee删除观察员,这可能会导致我的问题?

回答

46

啊。您正在观察来自SomethingElse对象的TekkPoint对象,并且SomethingElse对象是添加和删除观察者的对象,对吗? (这是事情完成的正常方式;我只是想澄清。)

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

如果你在观察物体的观察者消失之前,它可能会消失计划,那么你就需要通知他们应该删除其观察员观察员的一些方法。你TekkPoint可能会对这也将被SomethingElse观察到alive属性,当它被设置为NO那么大家观察TekkPoint将消除自理作为观察员。

2

您是否打电话给[super dealloc]之前您删除了您的观察员?过早调用super的dealloc可能会导致这样的错误。

+0

不,我绝对有正确的顺序。 [super dealloc]是我在dealloc中调用的最后一个东西。 – 2009-06-13 15:39:19

+0

旧线程,但只是碰到它。是的,超级dealloc绝对应该是最后的。 – Ben 2010-12-06 23:32:13

-10

正常的代码看起来是这样的:

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

仔细检查你的dealloc方法的签名(目标C是非常无情的,绝不会警告你,当你陷入困境的方法的名称)。例如,如果你的方法名称是“dealoc”(有一个l),你的dealloc永远不会被调用。

否则,编辑你的问题,包括你的dealloc reoutine。

+12

与键值观察无关。 – rpetrich 2011-04-08 19:19:41

+0

这个问题是为KVO不通知 – 2015-12-17 10:38:01

0

,为什么你叫

[super dealloc] 

从苹果公司的文件上的dealloc

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