我在小型上传软件中的想法是对所有任务(之前定义)始终使用相同的对象,我只是添加和删除事件并发出请求,因为参数总是相同的(相同的方法,相同的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+")");
}
如何获得“未知功能”的名称?我担心会留下事件......
答案 0 :(得分:2)
您可以设置几个简单的类来管理事件侦听器的集合。让我们调用集合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();
答案 1 :(得分:1)
假设重置了处理程序并保留了对象的实例,您只需在addEventListener()
函数中将useWeakReference
设置为true即可进行垃圾回收。
但是,更好的设计模式是将服务方法抽象为类。
然后,调用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);
}
}
}
答案 2 :(得分: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;
答案 3 :(得分:0)
查看我之前对Is There A Way To Remove Events Easier?的回答。基本上,没有简单的方法可以做到这一点。在那个答案中,我通过简单地覆盖事件监听器方法,将一个简单的方法放在一起来跟踪添加到类中的事件。使用该方法,您只需调用removeAllEventListeners()
即可完成。它工作得相当好,只要你一直记得调用该函数(否则事情永远不会从内存中删除)。
然而,对于大多数情况来说,这是过度的。我目前正在将它用于大型应用程序并且它已经帮助很大,但是对于简单的事情,它只会为您的应用程序添加额外的计算和内存消耗。