無名イベントリスナの作成時の注意点

May 30, 2006category: Flash 

イベントリスナを関数内のローカル変数として作成することは多々ある。例えば、以下のようなコードだ。このコードは、ファイルパスを与えて、対象のファイルをロードする関数である。ロードの実行には、メモリ上に確保された 1 つのローダを使い回している。

function loadSomething(path:String):Void {
  var listener:Object = new Object();
  listener.onLoad = function(event:Object):Void {
    trace("loaded");
  };
  this.fooLoader.addEventListener("onLoad", listener);
  this.fooLoader.load(path);
}

このイディオムは手軽で強力なのだが、リスナをイベントソースから削除していないので痛い目を見る。上記の loadSomething() を n 回実行した場合、trace の総数は n ではなく、等差数列 (a1+an)n/2 に従って増加してゆく。

では、ローカル変数として定義したリスナを削除するにはどうすればよいか。コードを下記のように変更すればよい。

function loadSomething(path:String):Void {
  var listener:Object = new Object();
  listener.onLoad = function(event:Object):Void {
    event.target.removeEventListener(event.type, this);
    trace("loaded");
  };
  this.fooLoader.addEventListener("onLoad", listener);
  this.fooLoader.load(path);
}

event.target は fooLoader を意味し、event.type は onLoad に等しい。つまり、イベント発生時にリスナが破棄されることになる。

ロードイベントのような一過性のイベントでは、ローダ自体もローカル変数として定義する方法がある。しかし、ロードを中断させる際などに、ローダへのアクセスが困難となるデメリットもある。

comments (0)このエントリーを含むはてなブックマークはてなブックマーク - 無名イベントリスナの作成時の注意点

comments