Actionscript 3 如何删除as3中具有未知函数的事件侦听器?
在一个小型上传软件中,我的想法是对所有任务(之前定义)始终使用相同的对象,我只是添加和删除事件并发出请求,因为参数总是相同的(相同的方法,相同的url…) 每当请求完成时,我都会删除侦听器,以便可以再次使用相同的对象 问题是当发生错误时,侦听器调用函数ioerror,但如果没有错误,我不知道应该调用什么函数:Actionscript 3 如何删除as3中具有未知函数的事件侦听器?,actionscript-3,events,Actionscript 3,Events,在一个小型上传软件中,我的想法是对所有任务(之前定义)始终使用相同的对象,我只是添加和删除事件并发出请求,因为参数总是相同的(相同的方法,相同的url…) 每当请求完成时,我都会删除侦听器,以便可以再次使用相同的对象 问题是当发生错误时,侦听器调用函数ioerror,但如果没有错误,我不知道应该调用什么函数: private function ioerror(e:IOErrorEvent){ e.target.removeEventListener(Event.C
private function ioerror(e:IOErrorEvent){
e.target.removeEventListener(Event.COMPLETE, unknownfuncion);
e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
msg("Error somewhere ("+e.text+")");
}
如何获得“未知函数”的名称?我担心的是留下事件…假设处理程序被重置并且对象的一个实例被保留,您可以在垃圾收集函数中将
usewakreference
设置为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);
}
}
}
假设处理程序被重置并且对象的一个实例被保留,您可以在垃圾收集函数中将
usewakreference
设置为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);
}
}
}
如果您知道可以作为侦听器添加的所有函数,那么您可以删除它们。将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;
如果您知道可以作为侦听器添加的所有函数,那么您可以删除它们。将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;
看一看我以前对这个问题的回答。基本上,没有简单的方法可以做到这一点。在这个答案中,我提出了一种简单的方法来跟踪添加到类中的事件,方法是简单地重写事件侦听器方法。使用该方法,您只需调用
removeAllEventListeners()
,即可完成此操作。只要您始终记得调用该函数,它就工作得相当好(否则就永远不会从内存中删除内容)
然而,在大多数情况下,这都是过火了。我目前正在将它用于一个大型应用程序,它帮助很大,但简单来说,它只会给你的应用程序增加额外的计算和内存消耗,这是不必要的。看看我以前对这个问题的回答。基本上,没有简单的方法可以做到这一点。在这个答案中,我提出了一种简单的方法来跟踪添加到类中的事件,方法是简单地重写事件侦听器方法。使用该方法,您只需调用
removeAllEventListeners()
,即可完成此操作。只要您始终记得调用该函数,它就工作得相当好(否则就永远不会从内存中删除内容)
然而,在大多数情况下,这都是过火了。我目前正在将它用于一个大型应用程序,它有很大的帮助,但对于一些简单的应用程序,它只会为您的应用程序添加不需要的额外计算和内存消耗。您可以设置几个简单的类来管理一组事件侦听器。让我们调用集合
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>[];
}
}
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);
这样,您可以像这样添加事件侦听器:
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>[];
}
}
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();
您可以设置几个简单的类来管理事件侦听器的集合。让我们调用集合
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>[];
}
}
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);
这样,您可以像这样添加事件侦听器:
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>[];
}
}
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();
这根本行不通。询问者不需要知道调用事件的是什么,他们需要知道当前绑定到完全独立的事件侦听器的函数是什么,这样他们就可以删除特定的侦听器作为后续,我的评论是在建议编辑
arguments.callee
之前做出的。显然,我的评论不再适用。目前的答案是相当有效的,尽管它与Aralicia提供的答案没有什么不同(除了将其抽象为一个单独的方法,这将是处理这种情况的正确方法),但这根本不起作用。询问者不需要知道调用事件的是什么,他们需要知道当前绑定到完全独立的事件侦听器的函数是什么,这样他们就可以删除特定的侦听器作为后续,我的评论是在建议编辑arguments.callee
之前做出的。显然,我的评论不再适用。目前的答案是相当有效的,尽管它与Aralicia提供的答案没有什么不同(除了将其抽象为一个单独的方法,这将是处理这种情况的正确方法),但这对于大型复杂软件非常有用。在我的例子中,我将创建一个简单的函数并添加所有需要的事件移除程序。到目前为止,我们必须始终以各种方式跟踪所有听众。谢谢。@GustavoPinent是的,正如我所提到的,当您在创建大规模应用程序时,手动跟踪可能添加或可能不添加的侦听器是不可行的,它非常有用。对于较小的应用程序,最好只是手动跟踪它们,因为您通常确切地知道要添加什么。有更好的设计来抽象这种类型的重用。@jasonstrugges,例如?我仍在尝试优化我的应用程序,所以欢迎对我的设计进行任何改进。也许,我不知道我是否“重新创建”了对象(obj:URLLoader)=