【问题标题】:how do I delete/gc an object in Actionscript 3?如何在 Actionscript 3 中删除/gc 对象?
【发布时间】:2010-10-17 02:22:49
【问题描述】:

我想从内部删除/强制对类实例进行垃圾回收。显然,this = null 和 delete this 不起作用。有什么办法可以做到这一点,还是我吠错了树?我基本上是在寻找某种析构函数..

我有一个尝试加载 XML 文件的类实例,如果找不到该文件,我想销毁该实例,最好从其内部销毁。重点是在父类中根据子实例是否为空来做一些事情。

我曾考虑向父级抛出一个事件并从那里删除子级,但我宁愿只在没有其他方法的情况下这样做。

【问题讨论】:

    标签: flash actionscript-3 oop class


    【解决方案1】:

    您不应该尝试从自身移除对象 - 这是一种不好的做法,在 AS3 中您不能确定这样做。

    对象可能仅在没有对该对象的引用时才被删除(即垃圾收集)。由于引用总是按值传递,并且对象通常不知道存在哪些对它的引用,因此您不能从自身中删除对象。您可以做的唯一有用的事情是创建一个方法来清理实例使用的所有资源。这种方法将用作析构函数,但您必须手动调用它。不要忘记事件侦听器也会阻止垃圾收集,除非您删除它们。

    delete'ing 属性和将其设置为 null 之间也有区别。实际上delete 将从动态类的实例中删除一个属性。而将属性值设置为 null 不会删除该属性,但会删除存储在那里的任何引用。因此,这两个操作都会破坏存储在某个属性中的引用。请注意,您不能delete 一个对象,只能是一个属性。

    在 Flash 播放器 9 和更早版本中,可以使用某些 hack 来启动垃圾收集。然而最近System.gc() 电话可用,它做同样的事情。请注意,您不能真正依赖实际调用 GC 的事实。这取决于 Flash 播放器。

    回到您的问题: 抛出事件并通知父母出现问题实际上是一个好主意。你应该坚持下去。此外,如果 parent 以这种方式知道此类事件会更好,而不是当它发现某些属性被神奇地为空时。

    P.S.:在 Flash Player 中阅读 Grant Skinner articles on memory 实际上是个好主意。

    【讨论】:

    • "注意,你不能删除一个对象,只能删除一个属性。" - 我不确定你的意思。如果我的属性是一个对象怎么办?
    • @Luke:我的意思是对象 A 的属性可能包含对某个对象 B 的引用,但 delete A.prop 只会删除该属性以及引用。 IE。 A 将不再拥有prop 属性,但可能会在某处留下对对象 B 的引用。所以 B 不会被 GC 处理。
    • System.gc() 仅适用于 Flash 播放器的调试版本。你应该修改一下,它不应该用于除调试以外的任何事情。
    • @Jonathan Dumaine:感谢您的评论。但是我想很明显,“你不能真正依赖”部分暗示 System.gc() 在生产代码中几乎没有用处。此外,如果程序员不尝试查阅文档,那么由此产生的问题完全是他的错。为您的评论 +1 以突出问题。
    【解决方案2】:

    如果使用 addChild() 方法将对象添加到 DisplayContainer,则可以使用 parent.removeChild(this) 从对象内从容器中删除对象。如果在那之后没有对对象的引用,它将被垃圾收集器拾取。

    唯一的问题是当您在对象中有事件侦听器时,您可以手动删除它,也可以通过在所有侦听器上设置 weakReference=true 让垃圾收集器为您完成。

    【讨论】:

      【解决方案3】:

      AS3 没有给你任何析构函数。您可以做的最好的事情是将所有引用设置为null 并保持手指交叉——GC 会注意到它并释放内存。

      【讨论】:

      • 好的,但是如何从内部设置类实例为空?
      • @evilpenguin,除非您使用单例,否则不要从类本身内部执行此操作。您可以从已实例化该类的类中执行此操作。
      • @evilpenguin:按照建议,你必须从外面做。
      【解决方案4】:
      System.gc()
      // Forces the garbage collection process. 
      

      参考:

      http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/System.html

      【讨论】:

      • quote:仅适用于 Flash Player 调试器版本和 AIR 应用程序所以对我来说几乎没有用处。
      【解决方案5】:

      您应该先阅读有关垃圾收集的内容,Grant.S 写了一篇很好的文章:

      http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

      重点不是将类本身设置为空,而是删除其所有引用,包括侦听器。一旦它完全成为孤儿,垃圾可能会在某一时刻捡起它。

      基本示例:

      // References a newly created sprite
      var reference:Sprite = new Sprite();
      
      // Removes the reference, the Sprite is now orphaned and will probably be garbage collected within some seconds.
      reference = null;
      

      一个好的做法是在您的所有类上系统地创建一个“destruct”方法,以删除其所有内部引用、处理位图、删除事件侦听器等,此后您只需担心取消链接外部的。

      如果您使用 FLEX Builder,则可以使用分析器来可视化 Flash Player 在内部处理所有这些的方式。

      【讨论】:

        【解决方案6】:

        这是从GSkinner 强制进行垃圾收集的一种不受支持的方式。

        try {
           new LocalConnection().connect('foo');
           new LocalConnection().connect('foo');
        } catch (e:*) {}
        // the GC will perform a full mark/sweep on the second call.
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-03-25
          • 1970-01-01
          • 1970-01-01
          • 2015-09-13
          • 2011-01-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多