0

我在一个小型上传软件中的想法是对所有任务(之前定义)始终使用相同的对象,我只需添加和删除事件并发出请求,因为参数总是相同的(相同的方法,相同的 url ... )。

每当请求完成时,我都会删除侦听器,以便可以再次使用相同的对象。

问题是发生错误时,侦听器调用函数 ioerror,但如果没有错误,我不知道应该调用什么函数:

private function ioerror(e:IOErrorEvent){
                e.target.removeEventListener(Event.COMPLETE, unknownfuncion);
                e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
                msg("Error somewhere ("+e.text+")");
            }

如何获得“未知功能”的名称?我害怕把事件抛在脑后……

4

4 回答 4

2

您可以设置几个简单的类来管理事件侦听器的集合。让我们调用 collection EventBatch,它可能如下所示:

public class EventBatch
{

    private var _items:Vector.<EventBatchItem> = new <EventBatchItem>[];


    public function addListener(target:IEventDispatcher, type:String, callback:Function):void
    {
        var item:EventBatchItem = new EventBatchItem(target, type, callback);
        _items.push(item);

        target.addEventListener(type, callback);
    }


    public function removeAll():void
    {
        for each(var i:EventBatchItem in _items)
        {
            i.target.removeEventListener(i.type, i.callback);
            i.dispose();
        }

        _items = new <EventBatchItem>[];
    }

}

这是代表项目的随附模型:

internal class EventBatchItem
{

    private var _target:IEventDispatcher;
    private var _type:String;
    private var _callback:Function;


    public function EventBatchItem(target:IEventDispatcher, type:String, callback:Function)
    {
        _target = target;
        _type = type;
        _callback = callback;
    }


    internal function dispose():void
    {
        _target = null;
        _callback = null;
    }


    internal function get target():IEventDispatcher{ return _target; }
    internal function get type():String{ return _type; }
    internal function get callback():Function{ return _callback; }

}

这样,您可以像这样添加事件侦听器:

var batch:EventBatch = new EventBatch();
batch.addListener(urlLoader, Event.COMPLETE, completeHandler);
batch.addListener(urlLoader, SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
batch.addListener(urlLoader, IOErrorEvent.IO_ERROR, ioErrorHandler);

在任何这些侦听器函数中,只需使用以下.removeAll()方法:

batch.removeAll();
于 2013-05-22T00:53:19.253 回答
1

假设处理程序被重置并且对象的一个​​实例被保留,你可以简单地在你的垃圾收集函数中设置useWeakReference为 true 。addEventListener()

然而,更好的设计模式是将服务方法抽象到一个类中。

然后,调用dispose可以删除所有处理程序。

package
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;

    public class AbstractService extends EventDispatcher
    {

        public var data:Object;

        public var requestMethod:String = URLRequestMethod.GET;

        public var url:String;

        protected var urlLoader:URLLoader;

        protected var urlRequest:URLRequest;

        public function AbstractService()
        {
            super();

            urlLoader = new URLLoader();
            urlLoader.addEventListener(Event.COMPLETE, completeHandler);
            urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

        /**
         *
         * @param url
         * @param data String or URLVariables
         */
        public function load(url:String=null, data:Object=null, requestMethod:String=URLRequestMethod.GET):void
        {
            if (url)
                this.url = url;

            if (data)
                this.data = data;

            if (requestMethod)
                this.requestMethod = requestMethod;

            urlRequest = new URLRequest(this.url);
            urlRequest.data = this.data;
            urlRequest.method = this.requestMethod;

            urlLoader.load(urlRequest);
        }

        protected function completeHandler(event:Event):void
        {
        }

        protected function ioErrorHandler(event:IOErrorEvent):void
        {
        }

        protected function securityErrorHandler(event:SecurityErrorEvent):void
        {
        }

        public function dispose():void
        {
            urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
            urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

    }
}
于 2013-05-21T23:15:21.110 回答
1

如果您知道所有可能添加为侦听器的功能,则可以将它们全部删除。将 removeEventListener() 与实际上并未在侦听的方法一起使用什么也不做。所以你可以使用类似的东西:

private function ioerror(e:IOErrorEvent){
  // I know that Event.COMPLETE could be listened by function1, function2 or function3
  // I remove all of them
  e.target.removeEventListener(Event.COMPLETE, function1);
  e.target.removeEventListener(Event.COMPLETE, function2);
  e.target.removeEventListener(Event.COMPLETE, function3);
  e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
  msg("Error somewhere ("+e.text+")");
}

另一种可能性是跟踪变量中实际监听事件的方法。

public function doSomething() {
  loader.addEventListener(Event.COMPLETE, onCompleteSomething);
  listeningComplete= onCompleteSomething;
}
public function doSomethingElse() {
  loader.addEventListener(Event.COMPLETE, onCompleteSomethingElse);
  listeningComplete= onCompleteSomethingElse;
}

private function ioerror(e:IOErrorEvent){
  e.target.removeEventListener(Event.COMPLETE, listeningComplete);
  e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
  msg("Error somewhere ("+e.text+")");
}

private var listeningComplete:Function;
于 2013-05-21T23:22:44.750 回答
0

看看我之前对是否有办法更轻松地删除事件的回答?. 基本上,没有简单的方法可以做到这一点。在那个答案中,我整理了一种简单的方法来跟踪通过简单地覆盖事件侦听器方法添加到类中的事件。使用该方法,您可以调用removeAllEventListeners()并完成它。只要您始终记得调用该函数,它就可以很好地工作(否则永远不会从内存中删除内容)。

然而,这对于大多数情况来说是多余的。我目前正在将它用于大型应用程序,它提供了极大的帮助,但对于一些简单的事情,它只会为您的应用程序添加不必要的额外计算和内存消耗。

于 2013-05-21T23:22:53.733 回答