是和不是。孩子们不再位于舞台上,但他们仍然是父母的孩子,直到removeChild()
被调用。这可能是好是坏。显然,它非常适合重用对象,但对于内存管理可能很糟糕,因为这些对象只能在其父对象被垃圾回收时才能被垃圾回收。对于一个简单的应用程序,这通常很好。但是对于一些巨大的东西......不是那么多。
对于我现在正在处理的项目(30 页,50,000 行),我创建了一个轻量级的 GUI 框架来处理我的所有 DisplayObjects。除了 basicBitmap
和Shape
DisplayObject
s 之外的所有东西都扩展了一个扩展的类Sprite
。在那个类中,我有这个功能:
final public function destroy():void {
this.removeAllEventListeners();
var i:int, l:int, cur:DisplayObject;
l = this.numChildren;
for ( i = 0; i < l; i++ ) {
cur = this.getChildAt( i );
if ( cur is XISprite && !this.stopChildXISpriteDestroy ) {
( cur as XISprite ).destroy();
}
else if ( cur is Sprite ) {
( cur as Sprite ).removeChildren();
}
if ( cur is Bitmap && ( cur as Bitmap ).bitmapData && !this.stopBitmapDestroy ) {
( cur as Bitmap ).bitmapData.dispose();
}
if ( cur is Loader && !this.stopLoaderDestroy ) {
( cur as Loader ).unload();
}
if ( cur is Shape ) {
( cur as Shape ).graphics.clear();
}
}
cur = null;
i = l = NaN;
this.removeChildren();
}
它基本上对所有对象进行了硬擦除,并允许我轻松地为该类的所有子对象进行垃圾收集。我还在跟踪所有事件侦听器,因此流氓侦听器根本不可能阻止 GC(通过调用removeAllEventListeners()
)。我在类中还有一些受保护的标志,允许您停止对某个对象类型的破坏(因此,如果需要,我可以将 SWF 或图像加载到内存中)
这可能是矫枉过正,但内存消耗一直是这个应用程序中的一个问题,并且该功能确实有助于管理它。这可能超出了您的需要,因此您可以removeChildren()
使用默认参数调用,它将从父对象中删除所有子对象。
作为事后的想法:让您的 DisplayObjectContainers 尽可能简单。尽可能避免嵌套它们。第一个条件,我在每个作为 XISprite 的孩子的 XISprite 上调用 destroy很好,但如果有负载和负载的 XISprite 孩子可能是灾难性的,因为 destroy() 调用会相互堆积并冻结应用程序。