4

我在 flex 4.5 中有一个大型移动应用程序,使用“大”我的意思是大..

  1. 超过 50 次观看
  2. 50 多个自定义组件
  3. 10+ 自定义事件
  4. 50 多个自定义类(不是 UIComponents)
  5. 很多皮肤等等...

我从未删除过 EventListener,现在我正在查看 flash 分析器,我有很多内存泄漏。
我实际上认为使用navigator.pushViewornavigator.popView()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{}

一个事件监听器被触发后,我是否需要同时删除这两个事件监听器?
如果是,我是否需要同时删除 doSomething 和 doSomethingElse 中的两个事件侦听器?

在 addeventlistener 中使用弱引用会更好吗?
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调用ImageButton一个功能,然后调用如果navigator.pushView 我更改视图,我应该从每个按钮中删除每个 EventListener 吗?最好的地方在哪里?

如果我有一个包含 15000 个组件的视图,我是否必须在删除视图时手动删除添加到每个组件的所有事件侦听器???

编辑

当视图从舞台上删除时,我主要需要删除所有事件侦听器,而不是每次我想到一个替代方案时手动执行它,我创建一个简单的类......

包实用程序 { 导入 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 回答