removeEventListener の拡張

September 02, 2006category: Flash 

EventDispatcher.removeEventListener の第 2 引数には対象リスナへの参照が必要だが、ある関数内のローカル変数としてリスナを作成し登録してしまうと、関数を抜けた後、つまり参照を失った際に、そのリスナの解除が困難となる。

幸いにも (というか実装上)、EventDispatcher は、個々のイベントに対するリスナの一覧を内部で保持している。参照を失ったリスナを解除するには、そのリストごと破棄すればよい。勿論、他のリスナも解除されてしまうので注意。

以下は、EventDispatcher を継承した EventDispatcherExtended クラスの例。removeEventListener のみオーバーライドしている。第 2 引数が空ならば、全てのリスナを削除する。

import mx.events.EventDispatcher;

/**
 *  mx.events.EventDispatcher の拡張
 */
class org.dyndns.bitmap.events.EventDispatcherExtended extends EventDispatcher {
  
  /**
   *  コンストラクタ
   */
  private function EventDispatcherExtended() {}

  /**
   *  リスナを削除する
   *  @param event    イベント名
   *  @param listener イベントリスナ
   */
  public function removeEventListener(event:String, listener:Object):Void {

    //リスナが指定されていれば通常の動作
    if ((event != null) && (listener != null)) {
      super(event, listener);

    //リスナが指定されていなければ全て削除
    } else if ((event != null) && (listener == null)) {
      delete this["__q_" + event];
    }
  }
}

例として、EventDispatcherExtended を継承した Hoge クラスを定義する。

import org.dyndns.bitmap.events.EventDispatcherExtended;

/**
 *  Hoge
 */
class Hoge extends EventDispatcherExtended {

  /**
   *  コンストラクタ
   */
  public function Hoge() { }
  
  /**
   *  テスト
   */
  public function test():Void {
    var eventObject:Object = new Object();
    eventObject.type = "onTest";
    //イベントを配信する
    this.dispatchEvent(eventObject);
  }
}

クライアントは Hoge のインスタンスを持ち、listenHoge で Hoge.onTest イベントに対してローカル変数のリスナを登録する。また、releaseHoge では Hoge.onTest に対する全てのリスナを解除する。

import Hoge;

/**
 *  クライアント
 */
class Client {

  private var hoge:Hoge = null;

  /**
   *  コンストラクタ
   */
  public function Client() {
    this.hoge = new Hoge();
  }

  /**
   *  hoge をリスンする
   */
  public function listenHoge():Void {
    var listener:Object = new Object();
    listener.onTest = function():Void {
      trace("test");
    };
    this.hoge.addEventListener("onTest", listener);
  }

  /**
   *  hoge のリスンを解除する
   */
  public function releaseHoge():Void {
    this.hoge.removeEventListener("onTest");
  }

  /**
   *  実行
   */
  public function fire():Void {
    this.hoge.test();
  }
}

テストコード。

import Client;

var client:Client = new Client();

this.client.listenHoge();
this.client.listenHoge();
this.client.listenHoge();
this.client.fire();

this.client.releaseHoge();
trace("released");

this.client.listenHoge();
this.client.fire();

実行結果。ローカル変数のリスナを解除していることが判る。

test
test
test
released
test

comments (0)このエントリーを含むはてなブックマークはてなブックマーク - removeEventListener の拡張