我正确地进行AS3参考清理吗?

时间:2010-05-19 20:55:30

标签: flash reference actionscript-3

在我的fla文件的一个帧中(我们称之为第2帧),我加载了几个xml文件,然后将该数据发送到在该帧中初始化的类中,该类创建了一些定时器和监听器。

然后当这个课完成它的工作。我调用一个dispatchEvent并移动到第3帧。这个框架也做了一些事情,它被初始化并创建了一些事件监听器和定时器。完成后,我再次转到第2帧。

这应该像我需要的那样经常重复,所以我需要正确地清理引用,我想知道我是否正确地做了。

对于精灵,我这样做。

world.removeChild(Background); // world is the parent stage
Background = null;

对于其他类的实例,我这样做。

Players[i].cleanUp(world); // do any cleanup within the instanced class
world.removeChild(PlayersSelect[i]);

对于事件监听器,我这样做。

if(Background != null)
{
    Background.removeEventListener(MouseEvent.CLICK, deSelectPlayer);
}

对于计时器,我这样做。

if(Timeout != null)
{
    Timeout.stop();
    Timeout.removeEventListener(TimerEvent.TIMER, queueHandler);
    Timeout.removeEventListener(TimerEvent.TIMER_COMPLETE, queueCompleted);
    Timeout = null;
}

对于库图像,我这样做

if(_libImage!= null)
{
    s.removeChild(Images._libImage); // s is the stage
    _libImage= null;
}

对于主时间轴中的班级本身,我这样做

Frame2.removeEventListener("Done", IAmDone);
Frame2.cleanUp(); // the cleanup() does all the stuff above
Frame2= null;

即使我做了所有这些,当我第二次进入第2帧时,它运行1-2秒然后我得到很多空引用错误,因为过早调用了清理函数。

我正确地进行了清理吗?

什么可能导致事件过早发生?

2 个答案:

答案 0 :(得分:2)

对我而言,最关心的是清理你正在做的听众。为了避免侦听器清理中的任何错误,我总是检查该项是否存在,然后是否有监听器;因此:

if(item)
{
   if(item.hasEventListener(MouseEvent.CLICK))
   {
      item.removeEventListener(MouseEvent.CLICK,doSomething);
   }
}

我在移除孩子之前做了一个类似的检查:

if(item)
{
   if(this.contains(item))
   {
      this.removeChild(item);
      item.destroy()//or whatever you code is to clear that element of its own dependencies.
      item = null;
   }
}

答案 1 :(得分:0)

如果您希望能够在将对象设置为null后让垃圾收集器清理对象。 然后,当您添加一个eventListener时,使用弱引用,这允许垃圾收集器在其值为null时收集它。 请参阅addEventListener函数的参数:

addEventListener(type:String, 
                 listener:Function,
                 useCapture:Boolean = false, 
                 priority:int = 0, 
                 useWeakReference:Boolean = false)

因此,如果没有空引用,则必须将最后一个参数设置为false。

addEventListener(MouseEvent.MOUSE_OVER, function(), false, 0, true);
instead of
addEventListener(MouseEvent.MOUSE_OVER, function());

如果您有强引用eventListeners,则必须先使用removeEventLister函数手动删除它们,然后再删除引用的对象。

编辑: jordanx的例子是无效的,因为即使item为null,强引用仍然存在,并且仍然可以进行空指针。