this = null
和 delete this
无法起作用。是否有任何方法可以实现这一点,或者我正在走错路线?我基本上在寻找某种析构函数。我拥有一个类实例,试图加载一个XML文件,如果该文件未找到,我希望从其自身内部销毁该实例,最好的情况是这样做之后能够在父类中根据子实例是否为空执行一些操作。
我考虑过向父类抛出事件并从那里删除子实例,但如果没有其他方法,我更喜欢不这样做。
this = null
和 delete this
无法起作用。是否有任何方法可以实现这一点,或者我正在走错路线?我基本上在寻找某种析构函数。不应该尝试从对象本身中删除对象,这是一种不良实践,在AS3中你肯定无法这样做。
仅当没有剩余引用指向一个对象时,该对象才可能被删除(即垃圾回收)。由于引用始终按值传递,并且通常对象无法知道哪些引用指向自己,因此你无法从对象本身中删除对象。唯一有用的方法是创建一个方法,将清理实例使用的所有资源。这个方法将充当一个析构函数,但你必须手动调用它。不要忘记事件监听器也会防止垃圾回收,除非你将它们删除。
删除属性和将其设置为null
之间还有区别。实际上,delete
将从动态类的实例中删除属性。而将属性值设置为null
不会删除属性,但会删除存储在其中的任何引用。因此,这两种操作都会销毁存储在某个属性中的引用。请注意,你无法delete
一个对象,只能删除属性。
在Flash Player 9和旧版本中,可以使用某些技巧来启动垃圾回收。然而,最近System.gc()
调用已经可用,它可以完成相同的功能。请注意,你不能真正依赖于GC是否将被调用。这取决于Flash Player。
回到你的问题: 抛出事件并通知父级发生了错误实际上是个好主意。你应该坚持这个想法。此外,如果父节点知道这样的事件,而不是在其属性被神奇地置空时才发现,那么效果更好。
P.S.: 阅读Grant Skinner在Flash Player中关于内存的文章是一个好主意。 链接
如果使用addChild()方法将对象添加到DisplayContainer中,您可以通过使用parent.removeChild(this)从对象内部将对象从容器中移除。如果在此之后对该对象没有引用,则将由垃圾回收器处理。
唯一的问题是当您在对象内部有事件侦听器时,您可以手动删除它们或者通过在所有侦听器上设置weakReference=true让垃圾回收器为您处理。
System.gc()
// Forces the garbage collection process.
参考资料:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/System.html
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;
这里有一种不受支持的方法可以从GSkinner强制进行垃圾回收。
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*) {}
// the GC will perform a full mark/sweep on the second call.
AS3没有提供析构函数。你能做的最好的事情就是将所有引用设置为null
,然后祈祷垃圾回收器能够注意到并释放内存。
delete A.prop
只会删除该属性以及引用。也就是说,A将不再具有属性prop
,但可能仍然存在对对象B的引用。因此,B将无法被垃圾回收。 - dragonflySystem.gc()
只能在 Flash Player 的调试版本中使用。您应该修改说明以明确指出它不应该用于除调试之外的任何其他目的。 - Jonathan Dumaine