1

在我的关卡编辑器中的 ActionScript-3 中,每个关卡都有一个新对象。旧关卡对象从舞台上移除。所以只有 1 个级别的对象处于阶段。我不会将它们保存在数组中或希望垃圾收集为我处理它们的东西中。我的问题似乎是旧对象的方法仍然被事件侦听器引用,这些事件侦听器会向新对象和旧对象触发事件。旧对象不在舞台上,因此不可见,但在保存时我注意到旧关卡具有由编辑新关卡引起的状态。

现在:我怎样才能确定地处置我的物品?

编辑:我还有一些事件监听器添加到舞台(KeyDown,MouseMove)。可能这几个是问题,而其他刚刚添加到对象中的对象会自动与对象一起删除吗?

4

1 回答 1

2

userWeakReference一种方法是通过将ofaddEventListener()属性设置为 true来简单地设置事件侦听器以使用弱引用:

addEventListener(MouseEvent.CLICK, mouseClickHandler, false, 0, true);

更好的模式是设置监听器的生命周期,例如添加监听器Event.ADDED_TO_STAGE,然后移除它们Event.REMOVED_FROM_STAGE

在您的构造函数中,监听Event.ADDED_TO_STAGE

// listen for added to stage
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);

当您的课程添加到舞台时,应用您的听众并聆听Event.REMOVED_FROM_STAGE

protected function addedToStageHandler(event):void
{
    // remove added to sage handler, listen for removed from stage
    removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);

    // setup listeners for class
    addEventListener(MouseEvent.CLICK, mouseClickHandler);
    addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
    addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
    addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
}

当您的课程从舞台上移除时,移除剩余的听众:

protected function removedFromStageHandler(event):void
{
    // remove removed from sage handler
    removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);

    // remove listeners for class
    removeEventListener(MouseEvent.CLICK, mouseClickHandler);
    removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
    removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
    removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
}

更好的是dispose()为你的类实现一个函数:

public function dispose():void
{
    removeEventListener(MouseEvent.CLICK, mouseClickHandler);
    removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
    removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
    removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
}

通常我会IDisposable为我的类实现一个接口,然后将其处理为:

// remove children
while (numChildren > 0)
{
    var displayObject:DisplayObject = removeChildAt(0);

    if (displayObject is IDisposable)
        IDisposable(displayObject).dispose();
}
于 2013-06-10T05:15:11.867 回答