【问题标题】:Clarifications regarding weak references in actionscript listeners关于 actionscript 侦听器中的弱引用的说明
【发布时间】:2011-08-29 14:40:51
【问题描述】:

我了解弱引用的工作原理,但我对它在 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播放器是不是太天真了,它无法确定事件监听器是在同一个对象中定义的?

【问题讨论】:

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


    【解决方案1】:

    Flash 中垃圾回收的基本规则是,如果从时间线中(直接或间接)引用了一个对象,则不能对其进行垃圾回收。这意味着,如果您的类的实例没有被根显示列表中的任何位置引用(或被依次从根引用的对象等递归地引用),则无论它是否引用自己。

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

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

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

    来自文档here

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

    【讨论】:

    • 感谢您的回答。但是,正如您所说,在上述场景中,如果 Foo 符合垃圾回收条件,那么它是否不违反代码逻辑。例如,许多博客都认为将所有事件侦听器标记为弱是一种好习惯,但在上述情况下,它不会导致错误,因为我期望点击事件一直被触发?跨度>
    • 好吧,不管有些博客怎么说,你应该只在有意义的时候使用弱引用。如果您需要对象在内存中持久存在,请不要使用它。但是,我认为您的示例有点奇怪,因为您可能不应该首先创建这样的匿名对象。就垃圾收集示例而言,这很好,但作为实际的项目代码,您可能应该重新考虑。
    猜你喜欢
    • 2012-01-02
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2012-01-18
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    相关资源
    最近更新 更多