当我注册一个对象foo以从另一个对象栏接收KVO通知时(使用addObserver:...),如果我然后解除分配foo,我是否需要在-dealloc中removeObserver:forKeyPath:
向bar发送消息?
您需要-removeObserver:forKeyPath:
在-[NSObject dealloc]
运行之前使用删除观察者,所以是的,在-dealloc
您的类的方法中执行它将起作用.
比这更好但是有一个确定性的观点,无论拥有正在进行观察的对象拥有什么,都可以告诉它它已经完成并且(最终)将被释放.这样,无论何时实际取消分配,都可以在不再需要进行观察的事物时立即停止观察.
记住这一点非常重要,因为Cocoa中对象的生命周期并不像某些人认为的那样具有确定性.各种Mac OS X的构架自己会发送你的对象-retain
和-autorelease
,延长它们的寿命超出了,否则你可能认为这将是.
此外,当你转换到Objective-C垃圾收集时,你会发现-finalize
它将在非常不同的时间 - 并且在非常不同的环境中 - 运行-dealloc
.首先,终结发生在不同的线程上,因此您实际上无法安全地发送-removeObserver:forKeyPath:
到-finalize
方法中的另一个对象.
坚持内存(和其他稀缺资源)管理-dealloc
和-finalize
,并使用单独的-invalidate
方法有一个业主告诉你在一个确定的点用它做一个对象; 做一些事情,比如在那里删除KVO观察.您的代码的意图将更清晰,您将有更少的细微错误来处理.
我通过痛苦的经历获得了一些额外的信息:虽然NSNotificationCenter在垃圾收集下运行时使用归零弱引用,但KVO却没有.因此,在使用GC时,您可以避免移除NSNotificationCenter观察者(当使用retain/release时,您仍然需要移除观察者),但您仍然必须删除KVO观察者,正如Chris所描述的那样.