4

Flex 4.5 で大きなモバイル アプリケーションを使用しています。

  1. 50 回以上の閲覧
  2. 50 以上のカスタム コンポーネント
  3. 10以上のカスタムイベント
  4. 50 以上のカスタム クラス (UIComponents ではありません)
  5. たくさんのスキンなど...

EventListener を削除したことはありませんが、フラッシュ プロファイラーを見ていると、多くのメモリ リークが発生しています。
実際にnavigator.pushViewor navigator.popView()orを使用navigator.popToFirstView()すると、ビュー自体のすべてのオブジェクト/変数の参照が削除され、ガベージ化されると考えました。集めました..

コードを修正しようとしていますが、イベントリスナーの操作方法を理解するのに多くの問題があります...

考えられるすべてのケースを説明するのではなく、いくつかの例を使用すると簡単になると思います...

例 1:

private function XXX():void
{
  var x:ClassA = new ClassA();
  x.addEventListener(CustomEvent.GETA, doSomething);
  x.addEventListener(CustomEvent2.TESTB, doSomethingElse);
}
private function doSomething(e:CustomEvent):void{}
private function doSomethingElse(e:CustomEvent2):void{}

いずれかが起動された後、両方の eventListener を削除する必要がありますか?
はいの場合、doSomething と doSomethingElse の両方で両方のイベント リスナーを削除する必要がありますか?

addeventlistenerでweakReferenceを使用する方が良いですか?
x.addEventListener(CustomEvent.GETA, doSomething, false, 0, true);

例 2:

tileはTileGroupですが、すべてになる可能性があります...

protected function activate(event:ViewNavigatorEvent):void
{               
tile.removeAllElements();
for (var i:int = 1 ; i < functionCount.length ; i++)
{           
var t:ImageButton = new ImageButton();
t.label = "";
switch (functionCount.getItemAt(i))
{
    case "Val1":
        t.addEventListener(MouseEvent.CLICK,function():void{goToAgenda();});
    break;
    case "Val2":
        t.addEventListener(MouseEvent.CLICK,function():void{goToAdmin();});                                 
    break;
    case "Val3":
        t.addEventListener(MouseEvent.CLICK,function():void{goToMyStore();});                                   
        break;  
    case "Val4":        
        t.addEventListener(MouseEvent.CLICK,function():void{openBI();});
        break;  
}
  tile.addElement(t);
}

clickビューを変更しImageButtonnavigator.pushView 場合、すべてのボタンからすべての EventListener を削除する必要がありますか? それを行うのに最適な場所はどこですか?

15000 個のコンポーネントを含むビューがある場合、ビューを削除するときに、各コンポーネントに追加されたすべてのイベント リスナーを手動で削除する必要がありますか?

編集

ビューがステージから削除されたときに主にすべてのイベントリスナーを削除する必要があるため、代替案を考えて単純なクラスを作成するたびに手動で行うのではなく...

パッケージ utils { import mx.collections.ArrayCollection;

public class Evt
{
    public static var listaEvt:ArrayCollection = new ArrayCollection();

    private var object:* = null;
    private var event:* = null;
    private var functio:* = null

    public function Evt(obj:*, evt:*, funct:Function)
    {
        this.object = obj;
        this.event = evt;
        this.functio = funct;
    }           

    public static function addEvt(obj:*, evt:*, funct:Function):void
    {
        var t:Evt = new Evt(obj, evt, funct);
        listaEvt.addItem(t);
    }

    public static function clear():void
    {
        var tmpArr:ArrayCollection = new ArrayCollection();
        tmpArr.addAll(listaEvt);
        listaEvt = new ArrayCollection();
        for (var i:int = 0 ; i < tmpArr.length ; i++)
        {
            var t:Evt = tmpArr.getItemAt(i) as Evt;
            if (t.object != null && t.event != null && t.functio != null)
            {
                if (t.object.hasEventListener(t.event))
                    t.object.removeEventListener(t.event, t.functio);
            }
        }
    }
}
}

私のコードではいつでも、私が呼び出す弱参照は必要ありません(匿名関数も使用しています):

// t can be any component with a event associated...
var f:Function = function():void{navigator.pushView(FotoGallery,data);};
Evt.addEvt(t, MouseEvent.CLICK, f);
t.addEventListener(MouseEvent.CLICK,f);     

次に、新しいビューに入ると、簡単なことを行いますEvt.clear(); このアプローチは効果的ですか? それを改善/変更するためのアドバイスはありますか?

4

1 に答える 1

1

最終的に大規模なアプリケーションは、次の点で役立つ Swiz FrameworkPure MVCなどのフレームワークの恩恵を受ける可能性があります。

  • 制御の反転 / 依存性注入
  • イベントの処理と仲介
  • 非同期リモート メソッドの単純なライフ サイクル
  • アプリケーション コードから切り離されたフレームワーク

たとえば、Swiz は、メタデータ タグを使用して、表示リストからイベントをキャッチするか、UI 以外のソースから発生したイベントのディスパッチャを挿入して、イベントを仲介できます。

[Dispatcher]
public var dispatcher:IEventDispatcher;

[EventHandler( event="UserEvent.ADD_USER" )]
public function handleAddUserEvent( event:UserEvent ):void
{
    // do stuff
}

それ以外の場合は、前述のように、イベント リスナーでの弱参照はオプションです。

addEventListener(Event.COMPLETE, completeHandler, false, 0, true);

分離されたイベント処理を必要とするビューは、ステージから追加および削除される固有のライフサイクルに適応できます。addedToStage表示オブジェクトが表示リストからのシグナルを処理する準備ができたらリスナーを追加し、表示オブジェクトremovedFromStageがイベント処理を必要としなくなったらリスナーを破棄します。

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class MyClass extends Sprite
    {
        public function MyClass()
        {
            super();

            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        protected function addedToStageHandler(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);

            /* add event listeners here */
        }

        protected function removedFromStageHandler(event:Event):void
        {
            removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);

            /* remove event listeners here */
        }

        protected function dispose():void
        {
            /* any remaining cleanup */
        }

    }
}
于 2012-05-30T05:14:40.187 に答える