Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3337359
  • 博文数量: 530
  • 博客积分: 13360
  • 博客等级: 上将
  • 技术积分: 5473
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-13 13:32
文章分类

全部博文(530)

文章存档

2017年(1)

2015年(2)

2013年(24)

2012年(20)

2011年(97)

2010年(240)

2009年(117)

2008年(12)

2007年(8)

2006年(9)

分类:

2010-05-28 22:29:22

    很多开发人员都知道如何使用事件机制,但却不理解事件机制的基本工作原理。在这里我们探讨一下ActionScript 3的事件机制(无论是新手还是老手,我相信看到最后肯定对你有所帮助。

1. 首先来看一下事件机制中的几个基本概念:

  • event objects(这 里我们姑且叫它事件对象):所有的事件对象都是flash.events.Event或者其子类。比如说鼠标事件MouseEvent,计时器事件 TimerEvent。每个事件对象中都包括事件类型(type)和事件源(target),便于event listener知道该事件的类型以及是谁抛出这样的事件。
  • event dispatchers(姑且叫它事件源):是事件发起的主体。所有的dispatcher都是EventDispatcher或其子类。事件触发源必须提供API让listener进行对该事件的注册(register)。
  • event listeners(姑且叫它事件监听器):在AS 3.0中它往往表现为一个函数。我们必须为每个特殊的事件和事件源注册一个监听器,当事件发生的时候,事件源(dispatcher)会通知该监听器去处理制定的事件。

2. 如何注册监听器(registering Listener)
   在AS 3.0中可以通过下面的语法格式进行注册。
        testBtn.addEventListener(MouseEvent.CLICK,clickHandler);
   当然在Flex中还有另外一种格式,在mxml文件中对一个控件的事件直接制定一个处理函数,如

3. 如何删除监听器(removing Listener)
   在AS 3.0中以下面的格式进行删除
       testBtn.removeEventListener(MouseEvent.CLICK, clickHandler);
   应该很容易理解。
   但这里确有一点很重要:尽量删除你已经不再使用的事件监听器,这个涉及到Flex 内存泄漏的问题。

4. 理解事件阶段(Event Phases)
   我们把事件触发源分为两类:一类是那些显示在界面中的元素抛出的事件,一类是那些不在界面中显示的元素抛出的事件。很简单,举个例子:第一类如 URLLoader对象去load图片或其他资源所抛出的如complete事件,就属于第一类。界面上的一个按钮所抛出的click事件就是第二类,它会触发一个事件流,引发一系列的事件,它又分三个阶段:捕获(capture),执行(target) 和冒泡(bubble),姑且这样表达这三个阶段。

  • 捕获阶段(capture)
    在这个阶段,Flash Player会去查找事件的触发源,它是通过根显示元素(root display object)逐层向下寻踪,直到找到事件的发起源头,如你在button上click后,Flash Player找到该button对象。在这个阶段监视器(listener)默认是不会收到任何消息的(默认只在target和bubble阶段收到 消息)。
    如果你想在捕获阶段让listener收到消息并有所动作,那么你可以在注册的时候改变第三个参数为true,如下面的方法:object.addEventListener(MouseEvent.CLICK, onClick, true);
    该阶段听起来很陌生,事实上它很少使用。但它却在事件流中扮演很重要的角色。它可以在事件到达子元素(child elements)之前被application捕获,当然也就可以阻止事件到达子元素。
  • 目标执行阶段(target)
    在这个阶段是事件的执行阶段,也就是我们常用的用来处理事件流的代码。
  • 冒泡阶段(bubble)
    最后的这个阶段其实就是第一个阶段的逆向过程。它就是在事件代码执行完毕后通过子元素逐级向父元素发出该事件,一直到根元素。在这个阶段你不需要特别的为监听器指定什么,你只要正常的注册事件就可以了。监听器会在该阶段收到通知。但前提是该事件是能够bubble的。

5. 事件的优先级(Event Prioriy)
    事件优先级我们用的很少,但理解它却很重要,但你添加一个事件的时候你可以设置监听器的优先级,优先级越高,你的监听器函数会越早被调用到。当然两个优先级 相同的监听器是根据他们被添加的顺序来决定优先级的。这个优先级指的是在同一个事件阶段(如capture,target,or bubble).一次,事件处理的优先级是先看阶段再看优先级的。

6. 弱引用(Weak Reference)
    弱引用时事件处理中非常重要的概念。要理解它为什么这么重要,你首先要理解Flash Player是如何进行垃圾回收的(garbage collection).

    顾名思义,垃圾回收就是回收那些不再使用的资源,主要是内存资源,否则会致系统崩溃。

    Flash Player是通过引用计数器(reference counting)以及标记与清除(mark and sweep)来实现垃圾回收的。
    引用计数器简单的讲就是给每个对象分配的技术器,一旦该对象的计数器为0时,就表示该对象可能不再被使用,可以安全的清除了。它的弊端就是不能解决循环引用问题,一旦出现循环引用,就不能通过该方法进行垃圾回收。
    而标记与清除(mark and sweep)就是为了解决循环引用问题的。它是通过在程序中遍历每个活动的、可到达的节点,一旦发现一些节点是处在活动节点之外的,就被认为不再有用,就可以被回收了。
    这两种机制是联合运行在垃圾回收过程中来保证正确回收资源。但他们并不能回收程序错误导致的垃圾。而监听器的注册就最容易导致这个问题的发生。

阅读(1125) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~