Flex 2 におけるオブジェクトの作成と破棄
http://livedocs.macromedia.com/flex/2_jp/docs/00001401.htmlを読んでみて、Flexはイベントハンドラの削除を明示的にしないと、インスタンスがメモリが解放されないとのこと。
<mx:Button id="button1" click="myClickHander(event)"/>
という書き方は、そのSWFに永遠生き続けるオブジェクトに対してしかやってはいけないようだ。これはオブジェクトの生成と破棄を頻繁にするアプリにとっては痛い。毎回、addEventListener と removeEventListener を明示する必要がある。removeEventListenerのタイミングを計れない場合は、weakRef を true で(弱参照という)addEventListener してやる必要がある。
C# などのイベントはそのオブジェクト参照がなくなれば、イベントも一緒に消えるはず。Flex が Flash であることを感じさせるのは、イベントのバブルアップだ。VBを代表するクライアントアプリのGUIでは、たとえばフォームにラベルを貼ると、ラベルをクリックしたときのイベントはラベルにしか起こらない。しかし、Flexではフォーム(ウィンドウ)に対しても起こる。面白いサンプルがあった。
<?xml version="1.0"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="createLinkListener()"> <mx:Script><![CDATA[ private function linkHandler(event:MouseEvent):void { var url:URLRequest = new URLRequest("http://finance.yahoo.com/q/ cq?d=v1&s=" + event.target.label); navigateToURL(url); } private function createLinkListener():void { vb1.addEventListener(MouseEvent.CLICK,linkHandler); } ]]></mx:Script> <mx:VBox id="vb1"> <mx:LinkButton label="ADBE"/> <mx:LinkButton label="GE"/> <mx:LinkButton label="HD"/> </mx:VBox> </mx:Application>
LinkButton それぞれにイベントをマッピングしてやるよりも、親の VBox でまとめて処理したほうがリソース効率がよいというサンプルだ。
これは推測だが、EventListener は実際はコンポーネントごとにあるのではなく、SWF内でシングルトンの Map
…というのが、内部の仕組みではないかと。