2012-03-15 12 views

答えて

13

はこれを試してみてください。

e.currentTarget.removeEventListener(e.type, arguments.callee) 
5
  1. あなたは上記のコードで何やってはいけません。

  2. mgraphのコードは、イベントのcurrentTargetは(可能な、しかし非常に低い)removeEventListener()メソッドを持っていない場合は、アドバタイズとして動作するように失敗の小さなチャンスがあります。コンパイラの観点からは、エラーの起こりやすい汎用オブジェクトのメソッドを動的に解決しようとしますが、注意して処理する必要があります。これは、プログラマがどのようなオブジェクトを想定しているかを「知らなかった」ことを仮定していることを示しているため、危険です。前提条件は、解決策を見つけるのには優れていますが、それを実現するには同様に悪いことです。

あなたはあなたがそれをやった方法で何かを最適化を考えた場合、その後、ちょうどFYIこれは実際に(コンパイル済みのSWFファイル内の)シンボルテーブル内で一意(冗長)名を作成するより悪い圧縮を引き起こしSWF。

これを実験的に行っている場合、これは問題ありませんが、実際のプロジェクトではこのようなコードは避けてください。

もう1つ注意してください:trueとの比較は100%無駄です。そのような比較が意味をなさない場合(findObjectはいつでもfalseと評価される場合があります)、if (findObject) { ... }はコードと同等ですが短いバージョンです。 最後に、匿名関数に戻り値の型宣言がありません。実際にはあなたの例ではあまり変わっていませんが、コンパイラの警告が出るという点が異なります。型宣言の省略は、一般的には悪いスタイルです。

EDIT

public function addEventListener(type:String, listener:Function ...):void 
{ 
    this._listeners[type].push(listener); 
} 

public function dispatchEvent(event:Event):void 
{ 
    for each (var listener:Function in this._listeners[event.type]) 
     listener(event); 
} 

public function removeEventListener(type:String, listener:Function, ...):void 
{ 
    delete this._listeners[type][listener]; 
} 

あなたが実際にIEventDispatcherのを実装するとします(代わりに別のEventDispatcherを使用して - あなたがそうする理由を持っていることは、そのような理由は、ネイティブのEventDispatcherは、短期の非常識な量を生成していることですしかし、メソッドを所有しているオブジェクトにアクセスすることができないため、event.targetまたはevent.currentTurgetをコード内に複製することはできません。でる。

もう一つの例:

public class SomeEvent extends Event 
{ 

    private var _target:NotEventDispatcher; 

    public function SomeEvent(type:String, someTarget:NotEventDispatcher) 
    { 
     super(type); 
     this._target = someTarget; 
    } 

    public override function get target():Object 
    { 
     return this._target; 
    } 
} 

これは私が実際に現実の世界で見たものです、これは「匿名」でソートするメイトまたは類似のフレームワークのいずれかで使用された単一の静的インスタンスにすべてのイベントディスパッチャに接続しますいくつかの "母船イベントのディスパッチャー"。

私は必ずしもこのアプローチを正当化するわけではありませんが、技術的にはこれらのいずれかを行うことを止めるものはありません。私は上記の私の記事で言っていたことは、あなたがした場合、特定の状況では言語は、のように、あなたの事を約束していることである:

var dispatcher:IEventDispatcher; 
try 
{ 
    dispatcher = IEventDispatcher(event.currentTarget); 
    // now you can be sure this object has removeEventListener 
    dispatcher.removeEventListener(event.type, arguments.callee); 
} 
catch (error:Error) 
{ 
    // but what are you going to do here? 
} 

しかし、最も一般的なケースは、あなたが、その場合には、バブリングイベントに加入されるだろう、イベントからの退会を希望するかどうかはわかりません。targetまたはevent.currentTtarget - あなたが聞いているものがわからないからです。

+0

'currentTarget'が' EventDispatcher'ではない場合があります。私はそれがどんなに合理的に起こるのか見ていません... –

+0

私はあなたが嘲笑しているなら、 'eventory'を' e-currentTarget'と 'それは 'IEventDispatcher'です。 'EventDispatcher'をモックする簡単な方法に加えて、' EventDispatcher'を新しく追加しました。あなたが*イベントスタックを破るために*試しに出かけるか、またはイベントスタックの依存関係を意図的に満足させようとしない限り、 'e.currentTarget'はいつも' removeEventListener '定義されている...それは、私には、解決策の問題ではなく、不完全なモックです。 –

+0

あなたは今どこに行くのか分かります。 –

1

私はwvxvwに同意します。

あなたの問題にアプローチする別の方法は、あなたのENTER_FRAMEイベントの「状態」を制御するための変数持つことである。この例では

private var _state:String; 

private function init(e:Event):void { 
    addEventListener(Event.ENTER_FRAME, loop, false, 0, true); 
} 

private function loop(e:Event):void { 
    switch(_state) { 
     case "play": 
      // do play stuff 
      // when you want to pause 
      // goToPause(); 
     break; 
    } 
} 

// you can call the method below from a button or whatever you want 
private function goToPause():void { 
    _state = "pause"; 
    // do some stuff here 
    // when you are done, switch "_state" back to "play" 
} 

、あなたがENTER_FRAMEのために聞いておくが、それだけで物事ありません_state変数は "再生"に設定されています。またgoToPause方法でイベントリスナーを削除することができます。

private function goToPause():void { 
    _state = "pause"; 
    removeEventListener(Event.ENTER_FRAME, loop); 
} 

しかし、物事を切り替えるには、「_state」を使用してのいいところは、あなたが(addEventListenersとremoveEventListenersの混乱を持って終了していないということですループがどのくらい複雑になるかに応じて起こりうることです)、追跡しなければならないことです。

0

後でリスナーを削除する場合は、匿名関数呼び出しを使用しないでください。

public function main():void 
{ 
    //... 
    //some method, where you add event listener 
    //... 

    //adding enterFrame event listener 
    this.addEventListener(Event.ENTER_FRAME,enterFrameHandler); 

    //... 

} 

private function enterFrameHandler(e:Event) 
{ 

    if(findObject) // " == true" is not really necessary here. 
    { 
     // removing enterFrame listener: 
     this.removeEventlistener(Event.ENTER_FRAME,enterFrameHandler); 
    } 
} 
0

ただ、ここで言及した他の技術との完全を期すために、あなたが作成している機能は、非結合クロージャなので、あなたもあなたの機能とディスパッチャの両方を参照するためにその概念を活用することができます。

var callback:Function; 
var dispacher:IEventDispatcher = this; 
addEventListener(Event.ENTER_FRAME, callback = function(e:Event){ 

     if(findObject == true){ 
      dispacher.removeEventListener(Event.ENTER_FRAME, callback); 
     } 

}); 

通常のクローズドオーバーの可変ルールが適用されます。

関連する問題