在Cocoa中,当解除分配时,我需要从接收KVO通知中删除对象吗? [英] In Cocoa do I need to remove an Object from receiving KVO notifications when deallocating it?
问题描述
当我注册一个对象 foo 从另一个对象 bar 接收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观察那里的事情。您的代码的意图将更清晰,您将有更少的微妙错误来处理。
When I've registered an object foo to receive KVO notifications from another object bar (using addObserver:...), if I then deallocate foo do I need to send a removeObserver:forKeyPath:
message to bar in -dealloc?
You need to use -removeObserver:forKeyPath:
to remove the observer before -[NSObject dealloc]
runs, so yes, doing it in the -dealloc
method of your class would work.
Better than that though would be to have a deterministic point where whatever owns the object that's doing the observing could tell it it's done and will (eventually) be deallocated. That way, you can stop observing immediately when the thing doing the observing is no longer needed, regardless of when it's actually deallocated.
This is important to keep in mind because the lifetime of objects in Cocoa isn't as deterministic as some people seem to think it is. The various Mac OS X frameworks themselves will send your objects -retain
and -autorelease
, extending their lifetime beyond what you might otherwise think it would be.
Furthermore, when you make the transition to Objective-C garbage collection, you'll find that -finalize
will run at very different times — and in very different contexts — than -dealloc
did. For one thing, finalization takes place on a different thread, so you really can't safely send -removeObserver:forKeyPath:
to another object in a -finalize
method.
Stick to memory (and other scarce resource) management in -dealloc
and -finalize
, and use a separate -invalidate
method to have an owner tell an object you're done with it at a deterministic point; do things like removing KVO observations there. The intent of your code will be clearer and you will have fewer subtle bugs to take care of.
这篇关于在Cocoa中,当解除分配时,我需要从接收KVO通知中删除对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!