代码之家  ›  专栏  ›  技术社区  ›  evilpenguin

如何删除/gc Actionscript 3中的对象?

  •  20
  • evilpenguin  · 技术社区  · 17 年前

    我想从类实例内部删除/强制对其进行垃圾收集 . 明显地 this = null delete this 不要工作。这是我能做到的,还是我找错了人?我基本上是在找某种类型的析构函数。。

    我有一个试图加载XML文件的类实例,如果找不到该文件,我希望销毁该实例,最好是从实例内部销毁。然后,重点是根据子实例是否为null,在父类中执行一些操作。

    我曾考虑过向家长抛出一个事件,并从中删除孩子,但我更愿意这样做,除非没有其他方法。

    6 回复  |  直到 17 年前
        1
  •  22
  •   dragonfly    17 年前

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

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

    delete null . 有效地 删去 将从动态类的实例中删除属性。而将属性值设置为 无效的 不会删除该属性,但会删除存储在其中的任何引用。因此,这两个操作都将销毁存储在某些属性中的引用。注意,你不能 删去 一个对象,只是一个属性。

    在FlashPlayer9和更早版本中,有一些黑客可以用来启动垃圾收集。然而最近 System.gc()

    回到你的问题: 举办活动并通知家长出了问题其实是个好主意。你应该坚持下去。此外,如果父级通过这种方式知道这类事件,而不是在发现某些属性神奇地为空时,则更好。

    articles on memory 在flash中,播放器实际上是个好主意。

        2
  •  5
  •   Lankaras Loerepoot    16 年前

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

    唯一的问题是当对象中有事件监听器时,您可以手动删除该监听器,也可以通过在所有监听器上设置weakReference=true让垃圾收集器为您执行此操作。

        3
  •  1
  •   dirkgently    17 年前

    AS3没有给你任何析构函数。最好将所有引用都设置为 null 祈祷GC注意到它并释放内存。

        4
  •  1
  •   Konstantin Tarkus    17 年前
    System.gc()
    // Forces the garbage collection process. 
    

    参考:

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

        5
  •  1
  •   Theo.T    17 年前

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

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

    基本示例:

    // 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,您可以使用profiler来可视化Flash Player在内部处理所有这些问题的方式。

        6
  •  1
  •   jedierikb grijalvaromero    17 年前

    GSkinner .

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