Delegateの罠

いや、別に罠じゃないけど、間違いやすいかもと思ったのでメモしときます。
Delegate.create()は、あるスコープで関数を呼び出したい場合とっても便利だけど、
createというメソッド名が示す通り、戻り値として返ってくるのはFunctionへの参照ではなく
新しいFunctionです。
ここを勘違いすると以下のような失敗をしてしまいます。
僕もしました。

失敗例

//Testクラス
//マウスが押されたらonTestイベントを発行します
import mx.events.EventDispatcher;
class Test {
public var addEventListener:Function;
public var removeEventListener:Function;
private var dispatchEvent:Function;
function Test() {
EventDispatcher.initialize(this);
Mouse.addListener(this);
}
private function onMouseDown():Void {
dispatchEvent({type:"onTest"});
}
}
//フレームアクション
//一度だけTestクラスのonTestイベントを受け取りたい
import mx.utils.Delegate;
var test:Test = new Test();
//TestのonTestイベントのリスナーとして登録
test.addEventListener("onTest", Delegate.create(this, onTest));
function onTest():Void {
//TestのonTestイベントのリスナーではなくなる
//以後onTestイベントは受け取らない
test.removeEventListener("onTest", Delegate.create(this, onTest));
trace("onTest");
}

意図している動作は、
onTestイベントを一度だけ受け取りtraceするものですが、
何回クリックしても何度でもイベントを受け取ってしまいます。
Functionの参照をaddEventListenerで渡したい場合は
次のような感じになるのかな。

成功例

//フレームアクション
//一度だけTestクラスのonTestイベントを受け取りたい
import mx.utils.Delegate;
var test:Test = new Test();
//TestのonTestイベントのリスナーとして登録
var $onTest:Function = Delegate.create(this, onTest)
test.addEventListener("onTest", $onTest);
function onTest():Void {
//TestのonTestイベントのリスナーではなくなる
//以後onTestイベントは受け取らない
test.removeEventListener("onTest", $onTest);
trace("onTest");
}
カテゴリー: ActionScript2 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です