Flash AS3-removeChild()用于完全删除对象?
我正在制作一个小行星游戏,在我的主课上,我在处理飞船发射的子弹时遇到了一些问题 所有项目符号都属于“Bullet”类,并存储在主类中名为“bullets”的数组中。当项目符号退出屏幕时,将调用主类中的removeBullet(bulletID)Flash AS3-removeChild()用于完全删除对象?,flash,actionscript-3,object,removechild,Flash,Actionscript 3,Object,Removechild,我正在制作一个小行星游戏,在我的主课上,我在处理飞船发射的子弹时遇到了一些问题 所有项目符号都属于“Bullet”类,并存储在主类中名为“bullets”的数组中。当项目符号退出屏幕时,将调用主类中的removeBullet(bulletID) private function removeBullet(id:int) { removeChild(bullets[id]); bullets.splice(id); } 在Bullet类中,我有一个
private function removeBullet(id:int)
{
removeChild(bullets[id]);
bullets.splice(id);
}
在Bullet类中,我有一个enterFrame侦听器跟踪“stillHere”。因此,只要使用addChild将一个项目符号添加到主阶段,“stillHere”就开始在我的输出面板中弹出
我的问题是,即使在我调用removeBullet之后,“stillHere”仍然会在输出面板中弹出,这告诉我,我试图删除的对象仍然在内存中的某个地方
我能做些什么才能完全摆脱它呢?事件侦听器本身很可能就是它仍在内存中的原因。这不是一个测试某个东西是否被垃圾收集的好方法 而且,即使这是检查对象是否已被垃圾收集的好方法,收集也不是一个即时的过程。Flash Player仅在需要分配更多内存但无法分配时才运行gc 假设除了显示列表和项目符号数组之外,您没有其他对项目符号对象的引用,那么您所做的就足以让它被垃圾收集 编辑:回答关于是否有任何方法可以观察是否收集了某个对象的问题 可以将该对象用作弱键词典中的键
private var _dict:Dictionary = new Dictionary(true);
_dict[bullet] = "Bullet is still here...";
然后,每当您想检查项目符号是否仍然存在时,就使用for…in循环来迭代键
for(var key:* in _dict){
trace(key + " " + _dict[key]);
}
由于弱键词典的键在垃圾收集中不算作引用,因此这是可行的
如果你非常担心内存泄漏,你可能会考虑编写一个对象池,将旧的弹头对象从舞台上删除,然后再重复使用。通过这种方式,您永远不会允许垃圾收集任何项目符号,但您可能只会创建少量、有限数量的项目符号(即用户在给定时间在屏幕上同时看到的项目符号数量)。这可能是最好的解决方案,因为子弹可能有一个小的内存占用,你得到的奖金不强迫闪存清理你的垃圾。当垃圾被移除时,运行GC会导致性能下降,因此通过这种方法,尽可能避免甚至需要它是一件好事。
事件侦听器本身很可能是它仍在内存中的原因。这不是一个测试某个东西是否被垃圾收集的好方法 而且,即使这是检查对象是否已被垃圾收集的好方法,收集也不是一个即时的过程。Flash Player仅在需要分配更多内存但无法分配时才运行gc 假设除了显示列表和项目符号数组之外,您没有其他对项目符号对象的引用,那么您所做的就足以让它被垃圾收集 编辑:回答关于是否有任何方法可以观察是否收集了某个对象的问题 可以将该对象用作弱键词典中的键private var _dict:Dictionary = new Dictionary(true);
_dict[bullet] = "Bullet is still here...";
然后,每当您想检查项目符号是否仍然存在时,就使用for…in循环来迭代键
for(var key:* in _dict){
trace(key + " " + _dict[key]);
}
由于弱键词典的键在垃圾收集中不算作引用,因此这是可行的
如果你非常担心内存泄漏,你可能会考虑编写一个对象池,将旧的弹头对象从舞台上删除,然后再重复使用。通过这种方式,您永远不会允许垃圾收集任何项目符号,但您可能只会创建少量、有限数量的项目符号(即用户在给定时间在屏幕上同时看到的项目符号数量)。这可能是最好的解决方案,因为子弹可能有一个小的内存占用,你得到的奖金不强迫闪存清理你的垃圾。当垃圾被移除时,运行GC会导致性能下降,因此通过这种方法,尽可能避免甚至需要垃圾是一件好事。
因为您使用的是ActionScript,所以您无法直接控制对象何时被移除 真正的问题是事件侦听器仍在启动。显然,您可以通过在删除它们时调用removeEventListener
来解决这个问题
然而,更好的方法是在整个游戏中只有一个ENTER\u FRAME
listener。它需要单独推进所有游戏元素(飞船、小行星、子弹、碎片等)。此方法消除了您不小心忘记删除事件侦听器的任何机会,而且它还使代码更清晰,因为您可以看到元素在一个时间步长内更新的顺序
我的临时对象中通常有一个destroy
函数,其内容如下:
public function destroy():void {
stop(); // if it's a MovieClip
if(parent) parent.removeChild(this);
}
只要我调用这个函数,然后删除对对象的引用,它通常被收集
由于这个原因,我的代码很少在单个对象上有侦听器。因为在ActionScript中,您无法直接控制对象何时被删除 真正的问题是事件侦听器仍在启动。显然,您可以通过在删除它们时调用
removeEventListener
来解决这个问题
然而,更好的方法是在整个游戏中只有一个ENTER\u FRAME
listener。它需要单独推进所有游戏元素(飞船、小行星、子弹、碎片等)。此方法可消除您意外忘记删除事件侦听器的任何可能性,以及