【发布时间】:2009-06-30 14:56:00
【问题描述】:
当我有一个对象时,删除对它的所有引用就足以为垃圾收集器注册它,至少我听到的是这样。例如:
removeChild(object);
object = null;
不过我还是有点困惑,因为这是否意味着在这个对象的实例中创建的事件监听器也会被自动删除?或者有什么我需要做的吗?
【问题讨论】:
标签: actionscript-3 event-handling garbage-collection
当我有一个对象时,删除对它的所有引用就足以为垃圾收集器注册它,至少我听到的是这样。例如:
removeChild(object);
object = null;
不过我还是有点困惑,因为这是否意味着在这个对象的实例中创建的事件监听器也会被自动删除?或者有什么我需要做的吗?
【问题讨论】:
标签: actionscript-3 event-handling garbage-collection
啊,您已经触及托管代码中内存管理的关键:如果您是一个对象,并且您有对另一个对象的引用(即使它只是以事件侦听器的形式),那么您至少是在 GC 期间对象不会从内存中删除的原因之一。
对于显示对象,根据我的经验,几乎任何时候您想订阅事件调度器但不负责该调度器在内存中的剩余,您应该使用 弱参考选项:
myPublisher.addEventListener("myEvent", myHandlerFunction, false, 0, true);
在我最近遇到的几乎所有情况下,“false, 0, true”(其中 true 表示“使用弱引用”,大致翻译为“添加此侦听器,但不要将其作为调度程序不要从内存中清除”——有关更多信息,请参阅文档)是添加事件侦听器的正确方法。出于某种原因,很少有教科书或文档 sn-ps 说明了这种方法,这是不幸的,因为它提供了更直观的内存管理体验。我建议将其用作规则而不是例外。
希望对你有帮助!
【讨论】:
您应该考虑的重要一点是,如果对象 O 具有事件处理程序,即作为事件处理程序添加到 E 的方法,那么这也算作引用...除非您添加带有弱引用的处理程序...
如果你有一个闭包,它的外部范围包含对 O 的引用,那么这是一个引用 ...
你不需要删除所有对 O 的引用,也不需要为 GC 注册它...... GC 也会删除循环引用......它会删除内存中的所有“孤岛”,如果你愿意......只有“ peninsulae" 连接到内置对象的“大陆”,即定时器、显示列表、I/O 层等不被收集...
another post of mine 的最后一段稍微处理了这个话题……
是的,基本上,如果 O 获得 GCd,那么任何事件处理程序都会获得 GCd,除非有另一个对它们的引用......等等。
希望对您有所帮助.. :)
问候
back2dos
【讨论】: