Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flash AS3-removeChild()用于完全删除对象?_Flash_Actionscript 3_Object_Removechild - Fatal编程技术网

Flash AS3-removeChild()用于完全删除对象?

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类中,我有一个

我正在制作一个小行星游戏,在我的主课上,我在处理飞船发射的子弹时遇到了一些问题

所有项目符号都属于“Bullet”类,并存储在主类中名为“bullets”的数组中。当项目符号退出屏幕时,将调用主类中的removeBullet(bulletID)

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。它需要单独推进所有游戏元素(飞船、小行星、子弹、碎片等)。此方法可消除您意外忘记删除事件侦听器的任何可能性,以及