您的位置: 首页 > 技术文档 > 多媒体制作 > [AS3.0] 强大的事件机制
Flash中的打印控制 回到列表 为动态创建MovieClip指定鼠标事件
 [AS3.0] 强大的事件机制

作者:KingdaSun 时间: 2006-07-29 文档类型:原创 来自:蓝色理想

第 1 页 强大的事件机制 [1]
第 2 页 强大的事件机制 [2]
第 3 页 强大的事件机制 [3]
第 4 页 强大的事件机制 [4]

在讲listener 和 this关键字之前,我们先来讲讲一个高级话题:弱引用的使用原则

新手可以不看,因为暂时用不到。但这个话题很有必要。当设计大型RIA应用程序时,弱引用必须要了解。
弱引用从原则上来讲,其引入是为了防止无意识的对象保留(unintentional object retention)引起的内存泄漏。
什么是无意识的对象保留?一般情况下,对象的逻辑生命周期和实际生命周期应当相同。但是在某些情况下,比如事件侦听器机制,我们可能会创建一个引用,它在内存中生存的时间比我们预期的要长很多。比如说,下面的例子中,即使删掉了侦听器lis,但事件还是能被继续捕捉。这是由于并没有removeEventListenr,那么系统中还会保留着对侦听器的引用。
如果没有把addEventListener中对侦听器的持有改成弱引用,那么这个侦听器会一直存在、耗掉内存不被人发觉。但如果设成了弱引用,那么垃圾回收器过段时间后会将侦听器占用的内存回收,此时侦听器从物理意义上才真正的被销毁了。
在销毁之前,这个侦听器还会继续存在,继续作用。这就是为什么下例中虽然已经把useWeakReference设为了true,但是还是会有作用。
那么什么时侯垃圾回收器(Garbage Collector)才会来回收呢?
唔,这要看它高兴了,快的话10分钟,慢的话一个月。哈哈,开玩笑,垃圾回收器的工作时间咋一看确实是不可测的,但也有规律可循。但这个问题探讨在本系列教程中显得过于艰深,黑羽会单独撰文来说明垃圾回收器的部分工作机制。

那么推论来了,我们凭什么要把useWeakReference设为false呢?除非我们有意要让某个侦听器在失去了其他所有引用的时候还要工作,才有可能这样做。但谁会有这样疯狂的想法呢?道哥还是包世宏?
所以,我建议,大家不妨养成习惯,把useWeakReference设为true。
当然最好的做法是始终记得不用侦听器了,一定要removeEventListener。在这一点上,我们要坚持“始乱终弃”!

//这个是Document Class,建个fla,绑定这个class。忘了,就看我第三篇教程。
package
{
 import flash.display.MovieClip;
 import flash.events.EventDispatcher;
 import flash.events.MouseEvent;

 public class LearnEvents extends MovieClip
 {
  function LearnEvents() {
   var lis:Function = function () {
    trace ("听到了鼠标Click事件!");
   }
   var kingda_s:KingdaSprite = new KingdaSprite(0xFFCC00, "kingdaSquare");
   addChild(kingda_s);
   kingda_s.addEventListener(MouseEvent.CLICK, lis, false, 0, true); //瞧,最后一个参数,已经把弱引用设为true了
   lis = null;  //这一句,我已经从逻辑上删掉lis了,大家作证啊
   trace ("侦听器还在吗?:"+ lis);  //lis也确实指向null了。但你只要继续点击方块,你会发现Click事件仍然被捕捉到。
  
  }  
 }
}
import flash.display.Sprite;
import flash.events.MouseEvent;


//这个类就是画一个矩形,
class KingdaSprite extends Sprite {
 public var nickname:String;
 public var ColorNum:uint;
 
 //colorNumber就是#ffcc00这种类型的数,在AS3中推荐用新的uint型来标记它
 public function KingdaSprite(colorNumber:uint, nameString:String) {
  ColorNum = colorNumber;
  nickname = nameString;
  graphics.beginFill(ColorNum);
  graphics.drawRect(0,0,100,100);
  graphics.endFill();  
 }
 
}

Listener和As2.0有何不同,和this关键字的“改进了的记忆力”
DOM Level 3中规定的是用Object来做listener。该Object有用来处理事件的方法(method)。
AS3虽然是按照DOM Level 3事件机制设计的,但也不完全听话,有自己独立的想法。在AS3中,侦听器就是函数。也只能用函数来侦听。
其实在ActionScript3中,Function实质也是一种特殊的Object,和AS2.0有相似之处。
见我的文章:ActionScript高级技巧:深入了解Function
因此AS3.0为什么限定用Function,这和它的架构有关,不细说了。
但有趣的是,在AS3.0中,对IEventDispatcher的定义中,仍然按照DOM3标准用Object来做Listener。见黑羽上一篇教程和随后的评论。
那么问题来了,function中this关键字的指向会怎样?
AS2.0开发者对AS2.0 事件机制中 this关键字的水性杨花应该深有认识。如果用function做侦听器,那么谁发出事件,this就指向谁。这就等于对象之间乱搞关系,啊呀呀。所以MM派了一个Delegate代理警察类来管理。唉,糜乱的岁月不堪回首啊。

//ActionScript 2.0例子:拷贝以下代码到第一帧,拖一个button到舞台,命名为kingda_btn;
function lisFunc() {
 trace ("亲爱的,你会指向谁:"+ this.name);   //我们本意应当是指向_root;
}

kingda_btn.addEventListener("click", lisFunc); //点一下button,看看指向谁。

函数在哪个对象里(应该叫method),那么this就指向谁。不在对象里,那么就指向global。

//http://www.kingda.org
package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;   

    public class AddListener extends Sprite {
        public function AddListener() {

            //用package外面定义的类KingdaSprite创建一个实例,由于同文件中,所以不用import啦
            var outsideChild:KingdaSprite = new KingdaSprite(0x00FF00, "outside_sprite");
        addChild(outsideChild);//没有了这一句,你啥都看不到。
   
            outsideChild.addEventListener(MouseEvent.CLICK, inclassHandler);//注册类里面的侦听器
            outsideChild.addEventListener(MouseEvent.CLICK, outsideHandler);//注册类外面的侦听器                      
        }

        private function inclassHandler(event:MouseEvent):void {
            trace("类里面的侦听器侦听到MouseEvent事件: " + event);
     trace("this关键字指向:"+this);
        }
       
    }
}

function outsideHandler(event:MouseEvent):void {
      trace("类外面的侦听器侦听到MouseEvent事件: " + event);
      trace("this关键字指向:"+this);
}

import flash.display.Sprite;
import flash.events.MouseEvent;

//这个类就是画一个矩形,然后你点击这个矩形会发出标准鼠标click的事件
class KingdaSprite extends Sprite {
  public var nickname:String;
  public var ColorNum:uint;
 
    //colorNumber就是#ffcc00这种类型的数,在AS3中推荐用新的uint型来标记它
     public function KingdaSprite(colorNumber:uint, nameString:String) {
         ColorNum = colorNumber;
         nickname = nameString;                 
         graphics.beginFill(ColorNum);
         graphics.drawRect(0,0,100,100);
         graphics.endFill();
     }
}

出处:蓝色理想
责任编辑:moby

上一页 强大的事件机制 [3] 下一页

◎进入论坛Flash专栏版块参加讨论

相关文章 更多相关链接
看IconFactory化腐朽为神奇
AS3学习笔记
Flash中的打印控制
为动态创建MovieClip指定鼠标事件
Flash中的颜色矩阵
作者文章 更多作者文章
[FLASH]爽快使用XML
Document Class特色带来了什么?
AS3.0的类及绑定
【震撼】Flash 9 Alpha发布
与Flash9的一次亲密接触!
关键字搜索 常规搜索 推荐文档
热门搜索:CSS Fireworks 设计比赛 网页制作 web标准 用户体验 UE photoshop Dreamweaver Studio8 Flash 手绘 CG
站点最新 站点最新列表
周大福“敬•自然”设计大赛开启
国际体验设计大会7月将在京举行
中国国防科技信息中心标志征集
云计算如何让安全问题可控
云计算是多数企业唯一拥抱互联网的机会
阿里行云
云手机年终巨献,送礼标配299起
阿里巴巴CTO王坚的"云和互联网观"
1499元买真八核 云OS双蛋大促
首届COCO桌面手机主题设计大赛
栏目最新 栏目最新列表
浅谈JavaScript编程语言的编码规范
如何在illustrator中绘制台历
Ps简单绘制一个可爱的铅笔图标
数据同步算法研究
用ps作简单的作品展示页面
CSS定位机制之一:普通流
25个最佳最闪亮的Eclipse开发项目
Illustrator中制作针线缝制文字效果
Photoshop制作印刷凹凸字体
VS2010中创建自定义SQL Rule
>> 分页 首页 前页 后页 尾页 页次:4/41个记录/页 转到 页 共4个记录

蓝色理想版权申明:除部分特别声明不要转载,或者授权我站独家播发的文章外,大家可以自由转载我站点的原创文章,但原作者和来自我站的链接必须保留(非我站原创的,按照原来自一节,自行链接)。文章版权归我站和作者共有。

转载要求:转载之图片、文件,链接请不要盗链到本站,且不准打上各自站点的水印,亦不能抹去我站点水印。

特别注意:本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有,文章若有侵犯作者版权,请与我们联系,我们将立即删除修改。

您的评论
用户名:  口令:
说明:输入正确的用户名和密码才能参与评论。如果您不是本站会员,你可以注册 为本站会员。
注意:文章中的链接、内容等需要修改的错误,请用报告错误,以利文档及时修改。
不评分 1 2 3 4 5
注意:请不要在评论中含与内容无关的广告链接,违者封ID
请您注意:
·不良评论请用报告管理员,以利管理员及时删除。
·尊重网上道德,遵守中华人民共和国的各项有关法律法规
·承担一切因您的行为而直接或间接导致的民事或刑事法律责任
·本站评论管理人员有权保留或删除其管辖评论中的任意内容
·您在本站发表的作品,本站有权在网站内转载或引用
·参与本评论即表明您已经阅读并接受上述条款
推荐文档 | 打印文档 | 评论文档 | 报告错误  
专业书推荐 更多内容
网站可用性测试及优化指南
《写给大家看的色彩书1》
《跟我去香港》
众妙之门—网站UI 设计之道
《Flex 4.0 RIA开发宝典》
《赢在设计》
犀利开发—jQuery内核详解与实践
作品集 更多内容

杂⑦杂⑧ Gold NORMANA V2