メモリリーク対策のためにremoveEventListenerする方法の一考察
2008 年 11月 19 日AS3のメモリリークに関しては、数々のFlasherさんのブログで語られていますが、共通して「不要になったオブジェクトをnullするだけじゃなくて、そのオブジェクトの全てのイベントをremoveEventListenerしてね」ということが書かれていると思います。
僕もそこらへんを気をつけて、AS3でコーディングしていたりするのですが、たいてい、
不要になる = 表示リストから消すとき(removeChildするとき)
というのがほとんどなので、不要になるオブジェクトのクラスにREMOVED_FROM_STAGEのハンドラをつけて、その中で全てのイベントをremoveEventListenerしています。もちろんこの「Event.REMOVED_FROM_STAGEのハンドラ」自身もその中でremoveEventListenerしてます。
以下サンプルです。
-
package{
-
import flash.display.MovieClip;
-
import flash.events.Event;
-
import flash.events.MouseEvent;
-
-
public class TestMC extends MovieClip {
-
/**
-
* コンストラクタ
-
*/
-
public function TestMC():void
-
{
-
//クリックされたらどうのこうのをaddEventListener
-
addEventListener(MouseEvent.CLICK, mouseClick);
-
//マウスオーバーされたらどうのこうのをaddEventListener
-
addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
-
//マウスアウトされたらどうのこうのをaddEventListener
-
addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
-
//リムーブされたらどうのこうのをaddEventListener
-
addEventListener(Event.REMOVED_FROM_STAGE, removed);
-
}
-
-
//各種マウスイベントハンドラ
-
private function mouseClick(e:MouseEvent):void{trace("クリックされました");}
-
private function mouseOver(e:MouseEvent):void{trace("マウスオーバーされました");}
-
private function mouseOut(e:MouseEvent):void {trace("マウスアウトされました");}
-
-
/**
-
* removeChildされるときに実行
-
*/
-
private function removed(e:Event):void
-
{
-
//全てのイベントリスナーをリムーブ
-
removeEventListener(MouseEvent.CLICK, mouseClick);
-
removeEventListener(MouseEvent.MOUSE_OVER, mouseOver);
-
removeEventListener(MouseEvent.MOUSE_OUT, mouseOut);
-
removeEventListener(Event.REMOVED_FROM_STAGE, removed); //←このハンドラ自身もremoveする!
-
}
-
}
-
}
親クラスでこのTestMCのインスタンスを
-
mc:TestMC=new TestMC();
-
addChild(mc);
みたいにして作って表示させて、いらなくなったときは
-
removeChild(mc);
-
mc=null;
としてあげれば、不要となるオブジェクトの「Event.REMOVED_FROM_STAGEのハンドラ」が動いてくれて、その中に書いた「全てのイベントをremoveEventListenerする」処理が動いてくれます。
こんな感じで前もって「removeChildされるときに、イベント参照も全部消えておいておくんなさいまし」と書いておけば、不要になったタイミングで「あー、イベント消さなきゃ。addしたイベントなんだっけ。面倒くせーなー」とかならなくて便利かなと思います。
Tags: removeEventListener, メモリリーク
