有关动作脚本侦听器中弱引用的说明

时间:2011-08-29 14:40:52

标签: flash actionscript-3 event-handling garbage-collection weak-references

我理解弱引用是如何工作的,但我对它在actionscript事件监听器中的使用感到有点困惑。请考虑以下示例:

public class Rectangle extends MovieClip {
  public function Rectangle() {
    var screen:Shape=new Shape();
    screen.addEventListener(MouseEvent.MOUSE_OUT, new Foo().listen, false, 0, true);
    addChild(screen);
  }
}

public class Foo extends MovieClip {
  public function listen(e:MouseEvent):void {
    trace("tracing");        
  }        
}

现在,由于对Foo只有一个弱引用,如果垃圾收集器运行并且代码停止按预期工作,那么事件监听器Foo不会被垃圾收集吗?

弱事件侦听器场景是否仅针对同一类中的事件侦听器方法规定如下?

public class Rectangle extends MovieClip {
  public function Rectangle() {
    var screen:Shape=new Shape();
    screen..addEventListener(MouseEvent.MOUSE_OUT, listen, false, 0, true);
    addChild(screen);
  }

   public function listen(e:MouseEvent):void {
    trace("tracing");        
   }
 }

在上面的场景中,这是弱事件监听器的帮助吗?

如果Rectangle对象没有其他引用,则它是垃圾收集的候选者,但由于对象中有事件侦听器,因此事件调度程序保存对该对象的引用,即使没有其他引用对象(除了事件监听器持有的对象)。因此,它被防止被垃圾收集。这是为什么弱事件听众被处方的原因? Flash播放器是如此天真,它无法弄清楚事件监听器是在同一个对象中定义的吗?

1 个答案:

答案 0 :(得分:3)

Flash中的垃圾收集的基本规则是,如果从时间轴(直接或间接)引用对象,则不能对其进行垃圾回收。这意味着如果您的类的实例未从根显示列表中的任何位置引用(或者通过从根引用的对象,也可以递归引用),则无论它是否具有引用,都将收集它的实例。本身。

这也意味着两个相互引用但未以任何方式从根显示列表中引用的对象应该有资格进行垃圾回收。

事件侦听器中的弱引用选项主要是为了您不必手动删除事件侦听器。我个人倾向于不使用它,因为我喜欢完全控制对象何时标记为垃圾收集。

因此,在您的第一个示例中,Foo实例在所有情况下都符合垃圾回收的条件。在您的第二个中,Rectangle实例是否可以被垃圾收集取决于它是否从显示列表中引用。这方面的useWeakReference标志没有区别。

来自文档here

  

类级别的成员函数不受垃圾回收的限制,因此您可以将classWeakReference设置为true,而不需要对它们进行垃圾回收。如果对于作为嵌套内部函数的侦听器将useWeakReference设置为true,则该函数将被垃圾收集并且不再持久。如果您创建对内部函数的引用(将其保存在另一个变量中),那么它不会被垃圾收集并保持持久性。