理论学习
http://book.51cto.com/art/201006/208224.htm
http://developer.51cto.com/art/201008/218947.htm
实践学习
http://fhuan123.iteye.com/blog/326206
http://www.cnblogs.com/nianshi/archive/2010/05/13/1734565.html
http://hi.baidu.com/fenglei0213/blog/item/a688c8fcd35266f3fd037f20.html
http://liguoliang.com/2010/custom-event-must-override-clone-method/
Flex 自定义Event 低级错误一例: 未重写Clone方法, 导致类型转换失败
432 views December 10, 2010 by 老李
在Event监听并转发过程中, 因为没用重写Clone方法, 导致实例被Clone为普通Event实例.
情况是这样的:
自定义Event: EventTest: 继承Event, 增加了一些属性, 重写了toString(), 未重写Clone.
出现问题: 创建EventTest实例后, 多次监听并转发, 在监听, 转发过程中, Event实例对象被Clone, 因为未重写Clone方法, 会通过Event类的Clone方法进行复制, 仅会复制其EventType, 且类型为Event.
形象的说就是: eventTest –> 被监听到, 准发 ->框架Clone eventTest(EventTest类中未重写Clone方法, 于是eventTest被克隆为一个普通Event) –> 再次监听, Event类型不吻合, 报错.
公司代码规范中严格规定了自定义Event必须及时重写Clone与toString方法, 写了这么久, 我才领悟到原因. 败了
http://blog.youkuaiyun.com/lingwen20/archive/2009/08/21/4470510.aspx
“只有事件发送者才能侦听事件”,这句话的意思是dispatchEvent对象与addEventListener对象都必须是同一个实例,所发送的事件类型可以是系统自定义的事件也可以是任一类的静态常量。
在自定义事件派发与侦听过程中需要注意事件的流程,我们先要做的是建立侦听器(addEventListener),再发送事件,程序在执行dispatchEvent之后立马通知已注册事件侦听的所有对象,如果addEventListener语句在dispatchEvent之后,那么注册该侦听器的对象将无法接到通知。这一点在接收和发送数据时容易出问题,有时候很难弄明白dispatchEvent语句究竟是在什么时候执行的。
Settings.getInstance().loadSettings("customAs/xml/file.xml");
Settings.getInstance().addEventListener(Settings.INIT, onSettingsInit);
public function loadSettings(url:String):void {
var urlRequest:URLRequest = new URLRequest(url);
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, onXMLDataLoaded);
urlLoader.load(urlRequest);
trace("loadSettings");
}
private function onXMLDataLoaded(event:Event):void {
data = XML(urlLoader.data);
dispatchEvent(new Event(Settings.INIT, true, true));
dispatchEvent(new Event(Settings.FILE,true,true));
}
那么它执行的顺序就应该是先执行loadSettings("customAs/xml/file.xml"),进入loadSettings(url:String):void 函数,当执行到
urlLoader.addEventListener(Event.COMPLETE, onXMLDataLoaded)的时候,程序只是将urlLoader对象添加到侦听队列中,并没跳转去执行
onXMLDataLoaded(event:Event):void ,所以这个时候dispatchEvent(new Event(Settings.INIT, true, true))该条语句并未执行,也就是说Settings事件源并未派发事件。
执行完loadSettings(url:String):void 函数后,再执行
Settings.getInstance().addEventListener(Settings.INIT, onSettingsInit)语句,将Settings.getInstance()添加到Settings事件源的队列上,当customAs/xml/file.xm加载完后,Event事件源通知urlLoader对象执行onXMLDataLoaded函数,这之后才会派发 Settings.INIT事件,之后执行onSettingsInit函数