如果我添加一个将MovieClip或Sprite扩展到舞台的对象,并从舞台中删除该对象,在以下情况下是否需要destroy方法:
答案 0 :(得分:2)
如果删除对父对象的所有引用,则不必删除其子DisplayObject,或者使其成员变量为空,假设没有对这些子对象的外部引用。
Flash使用“标记扫描”垃圾收集器。为了确定哪些对象符合垃圾收集的条件,Flash从最顶层的Stage
元素开始,遍历它找到的任何引用,标记对象。任何未标记的对象都无法访问,并且有资格进行垃圾回收。
想象一个黑盒子对象。如果删除对此框的所有引用,则它将有资格进行垃圾回收。现在想象一下,这个黑盒实际上里面有很多子对象。尽管父黑盒子和子对象之间可能存在引用,但它并没有改变黑盒本身不可访问的事实,因此所有这些“内部”引用都无关紧要。这些对象将有资格进行垃圾回收。你已经从树中剪断了分支,即使分支本身可能有许多分支和较小的分支。
这是一个简单的例子:
var obj:MySprite = new MySprite();
obj.foo = new Foo();
obj.addChild(new Sprite());
addChild(obj);
我们如何清理obj
及其子组件?所有必要的是:
removeChild(obj);
obj = null;
现在obj
无法访问,其子组件也是如此。他们都有资格进行垃圾收集。
但是,如果您对这些子对象有任何外部引用,则应该小心:
var obj2:Sprite = new Sprite();
obj.addChild(obj2);
obj = null;
即使我们排除了obj
,我们也忘记了obj2
,因此它不会被垃圾收集。父{4}}对象也不会被垃圾收集,因为obj
引用它。如果obj2.parent
是我们的黑匣子,那么我们对obj
的引用指向黑匣子内部!
因此,在清理对象时清空和删除东西是一种好习惯,特别是在不清楚的混乱情况下。如果删除它们总是安全的,但最终可能会编写不必要的代码。
如果您想查看正在发生的事情,使用Flash Builder,FlashDevelop或FDT中的探查器工具来查看内存使用情况会很有帮助。如果要测试这些想法,可以使用System.gc()调用强制GC在调试模式下运行。