我在为垃圾收集创建清理函数时遇到了麻烦[例子里面]

时间:2012-01-09 22:52:26

标签: flash actionscript-3

我正在尝试使用全局清理功能,并传递MovieClip或TextField以进行删除。我想删除剪辑而不直接引用剪辑。任何帮助将不胜感激。

var clip:Sprite = new Sprite();
clip.graphics.beginFill(0x000000, 1)
clip.graphics.drawRect(0,0,100,100)
clip.graphics.endFill()
clip.name = "clip"
addChild(clip);

cleanup(clip)

function cleanup(mc):void {
    removeChild(mc.parent.getChildByName(mc.name));
    mc = null

    // clip is removed and traces as [object Sprite]
    trace(clip)

    //
    addChild(clip);
    removeChild(clip)
    clip = null

    // clip is removed and traces as null.
    trace(clip)
}

这是FLA(Flash cs4):http://dl.dropbox.com/u/4725599/test-cs4.zip

2 个答案:

答案 0 :(得分:3)

你似乎对范围有误解。我会试着解释你在做什么:

function cleanup(mc):void {
    removeChild(mc.parent.getChildByName(mc.name)); // removes the "clip" sprite
    mc = null; // nulls the local var "mc", which essentially does nothing

    addChild(clip);     // re-add the "clip" sprite
    removeChild(clip)   // remove the "clip" sprite
    clip = null;        // null the "clip" sprite, removing the last reference to the memory allocated for the sprite
}

基本上,当您创建Sprite时,您需要分配Sprite所需的内存并将其分配给clip变量。你的精灵现在有一个参考。

然后将其添加到舞台上。这会创建一个新引用,因此您的sprite现在有2个引用。就是这样。

mc函数中的cleanup()变量是一个临时变量 - 它们在函数退出后被清除,因此您无需担心它。基本上要标记您的Sprite垃圾收集,您需要删除它的2个引用:clip变量和阶段。所以你只需要这样做:

clip.parent.removeChild( clip );
clip = null;

已经完成了。

查看:http://divillysausages.com/blog/tracking_memory_leaks_in_as3(免责声明:我的网站)哪些内容可以很好地解释内存在as3中的工作原理

修改 通常你会根据类来工作。在我的所有类中,我实现了一个destroy()函数,我可以调用它来清理类(删除子节点,事件侦听器,对其他对象的任何引用等)。对于调用destroy()的代码,它不关心对象做什么或它是如何工作的,它只是知道后来该对象有利于垃圾收集。

作为一般原则,创造某物的物体也有责任将其摧毁。

答案 1 :(得分:1)

请记住,您正在做的事情 - 从父母的显示列表中删除显示对象 - 可能还不够。 要符合垃圾收集器的条件,必须删除分配给该对象的每个侦听器。并且,如果对象在别处被引用,例如在数组中,则不会正确地垃圾收集。 我所说的可能是尝试为GC编写函数并不容易。我通常手动处理每个对象。 希望它有所帮助!