addEventListenerの登録処理
addEventListenerの登録処理ではまったので、改めて調べてみた。
同じ関数
2重に登録されない。
addEventListener(FlexEvent.CREATION_COMPLETE, createComp1); addEventListener(FlexEvent.CREATION_COMPLETE, createComp1);
これはcreateComp1の処理が1回だけ呼ばれる。
useCapture引数が異なる
改めてドキュメントを読んでいたら、これは違うものとして登録されるとの事。
addEventListener(FlexEvent.CREATION_COMPLETE, createComp2, true); addEventListener(FlexEvent.CREATION_COMPLETE, createComp2, false);
実際に同じ関数、引数違いで行ったところ2回呼ばれた。まあ、呼ばれるタイミングが異なるので、関数が同じでも2回呼ばれるのは当然の動作。
無名関数
ちゃんと認識してなかったのはコレ。
private function initWnd():void { addEventListener( FlexEvent.CREATION_COMPLETE, function(e:FlexEvent):void { trace("creationComplete nameless"); } ); }
無名関数(というか関数内関数)はその呼び出し毎の都度生成のようで、関数呼び出し毎に別の関数が登録される事になる。ここで、initWndを2回呼び出すと結果として登録した処理も2回実行される。
実際に初期化処理を2回呼び出す事は無いと思うが、場面が変われば状況は違ってくる。何となくfunctionはグローバルな所に存在するイメージを持っていたみたいで、バグとして発生していた現象がすぐに理解できなかった。そういえば、無名関数と弱参照でイベント登録をして、うまく処理されないなぁといった事があったが、登録した無名関数がGCに回収されてたって事ね...
検証コード
実際に動作を確認したソース。無名関数の動作で明らかだけど、createComp1、createComp2の登録動作で、関数が異なる場合の動作も確認できる。
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300" initialize="init(event)"> <mx:Script> <![CDATA[ import mx.events.FlexEvent; private function init(e:FlexEvent):void { // 同じ設定の場合1回しか登録されない addEventListener(FlexEvent.CREATION_COMPLETE, createComp1); addEventListener(FlexEvent.CREATION_COMPLETE, createComp1); // useCapture引数が違う場合、別々に登録される addEventListener(FlexEvent.CREATION_COMPLETE, createComp2, true); addEventListener(FlexEvent.CREATION_COMPLETE, createComp2, false); // 無名関数で登録した場合、関数のオブジェクトが異なるので、 // 別々に登録される initWnd(); initWnd(); } private function createComp1(e:FlexEvent):void { trace("creationComplete 1") } private function createComp2(e:FlexEvent):void { trace("creationComplete 2", "phase : " + e.eventPhase); } private function initWnd():void { addEventListener( FlexEvent.CREATION_COMPLETE, function(e:FlexEvent):void { trace("creationComplete nameless"); } ); } ]]> </mx:Script> </mx:WindowedApplication>
実行結果。createComp1は1回、createComp2はタイミング違いで2回、無名関数は2回呼ばれている事が分かる。
creationComplete 2 phase : 1 creationComplete 1 creationComplete 2 phase : 2 creationComplete nameless creationComplete nameless