在我的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秒然后我得到很多空引用错误,因为过早调用了清理函数。
我正确地进行了清理吗?
什么可能导致事件过早发生?
答案 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,强引用仍然存在,并且仍然可以进行空指针。