内置对象addListener 的 Tip
CODE:
var _listener:Object = new Object();
_listener.onMouseDown = function() {
trace("-- Mouse Down");
};
trace("Mouse has "+Mouse["_listeners"].length+" listener before [removeListener].");
Mouse.removeListener(_listener);
trace("Mouse has "+Mouse["_listeners"].length+" listener after [removeListener].");
Mouse.addListener(_listener);
上面的代码在两次Ctrl+Enter之后,点击一次鼠标将会执行两次onMouseDown事件。实际上不仅仅是多次ctrl+Enter,只要_listener对象被回收之前没有removeListener,新产生的同名对象就会接收本该发给他“双胞胎兄弟”的消息(真正的主人已经不存在)。
根源在于flash中的引用机制。因为flash是解释型语言,对一个对象的引用是在执行的时候查询,_root.objectA引用的结果是运行到这一句AS的时候生成。当一个对象(例如MC)被删除,对该对象的引用并不会删除,一旦产生和这个对象同名的新对象,这些引用在运行到的时候会指向新对象。
回到listener的问题来,发现removeListener不起作用,这很好理解,删除listener的操作应该是遍历_listeners数组,如果数组成员等于该对象,就从数组中删除。对象相等的条件是指针地址相同,很明显,新旧对象的指针不同,所以removeListener没有结果(_listeners里面保留的还是旧的指针)。
广播事件的时候,是类似这样的代码:
var i=_listeners.length-1;
while(i--) _listeners[i][event]()
新旧_listeners[i] 引用都是指向新对象,于是事件被执行了2次。
要解决这种问题,尽量把侦听器设为不可销毁的对象(如_root),或者在对象销毁之前主动removeListener。
- 上一篇:测试 (一张wow截图)
- 下一篇:最近比较有印象的游戏
