1

レベル エディタの ActionScript-3 では、レベルごとに新しいオブジェクトがあります。古いレベルのオブジェクトはステージから削除されます。したがって、1 つのレベル オブジェクトのみがステージにあります。ガベージ コレクションによってそれらが破棄されることを期待して、それらを配列などに保持しません。私の問題は、古いオブジェクトのメソッドが、新しいオブジェクトと古いオブジェクトにイベントを発生させるイベントリスナーによってまだ参照されていることです。古いオブジェクトはステージ上にないため見えませんが、保存すると、新しいレベルを編集したために古いレベルが状態になっていることに気付きました。

今: オブジェクトを確実に処分するにはどうすればよいですか?

編集: また、いくつかのイベント リスナーがステージに追加されています (KeyDown、MouseMove)。それらのいくつかが問題であり、オブジェクトに追加されたばかりの他のものはオブジェクトとともに自動的に削除されるのでしょうか?

4

1 に答える 1

2

userWeakReference1 つの方法は、 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 に答える