在我的Flash项目中,我有一个有2个关键帧的movieclip。两个帧每个都包含1个动画片段。
第1帧 - Landing
第2帧 - Game
应用程序的流程很简单:
Landing
和Game
动画片段都链接到定义事件侦听器的单独类。问题是,当我在玩游戏后在第1步结束时,Game
事件监听器会针对各自的事件触发两次。如果我第三次完成这个过程,事件监听器会为每个事件触发三次。这种情况一直在发生,所以如果我循环应用程序流7次,事件监听器会触发七次。我不明白为什么会发生这种情况,因为在第1帧,Game
movieclip(我认为它的相关类实例)不存在 - 但我在这里显然遗漏了一些东西。
我也在其他项目中遇到过这个问题,并尝试通过首先检查事件监听器是否存在来修复它,如果不存在则只定义它们,但我最终得到的意外结果并没有真正解决问题。
我需要确保事件侦听器只触发一次。任何建议&我将非常感谢您的见解,谢谢!
答案 0 :(得分:2)
如果同一图层上有两个具有不同剪辑的帧,则每次该帧“进入”时,都会创建该剪辑。当它“离开”时,剪辑被移除,但它仍然会被保留,不会被垃圾收集。因此,下一次帧进入另一个剪辑时,“创建”并获得自己的监听器。最好的办法是在更改帧时删除侦听器。我通常在每个班级都有Event.REMOVED_FROM_STAGE
的听众来解决这类问题。如果它被删除,那么你清理剩余的监听器。
您可能还想尝试“弱听众”:
addEventListener(GameEvent.GAME_START, gameStartedHandler, false, 0, true);
“true”使链接“弱”,因此如果删除了一个对象,垃圾收集器就可以将其拾取。我不会完全依赖这个。最好手动删除引用,以便您确定。
这个答案假设很多。如果你发布代码/截图/闪光灯以便更好地诊断它会很有用。
答案 1 :(得分:2)
如果没有看到代码或知道您正在侦听哪些事件以及是谁/什么激发了它们,那么肯定很难知道。
但是,我的猜测是没有收集动画片段(这不一定是内存泄漏!)所以,它们仍然活着并且踢。您可能应该有一个方法将它们设置为“空闲”状态,可以这么说。意思是,你删除了监听器,停止计时器等。这个想法是让你的对象处于不运行任何代码的状态。
动画片段和其他显示对象的简单方法(通常足够好)是侦听ADDED_TO_STAGE和REMOVED_FROM_STAGE事件。这里的想法是,当你的对象被添加到舞台时,它会“激活”,在你的情况下,当你到达游戏类的第2帧时;当它被移除时,即当你回到第1帧时,它会“停用”。
这些方面的东西:
public class Game extends MovieClip {
private var _timer:Timer;
public function Game() {
addEventListener(Event.ADDED_TO_STAGE,init);
addEventListener(Event.REMOVED_FROM_STAGE,destroy);
}
private function init():void {
// your init code goes here
// just an example:
_timer = new Timer(33);
_timer.addEventListener(TimerEvent.TIMER,mainLoop);
_timer.start();
trace("init");
}
private function destroy():void {
_timer.stop();
_timer.removeEventListener(TimerEvent.TIMER,mainLoop);
trace("destroy");
}
private function mainLoop(e:TimerEvent):void {
// code for main loop here...
trace("mainLoop");
}
}
检查跟踪以查看其是否正常工作。你应该看到“init”被追踪出来,然后是“mainLoop”,只要你留在第2帧,当你回到第1帧时“毁掉”。“mainLoop”应该停止追踪。
除此之外,你可能想要检查没有内存泄漏(事实上你有7个实例并不一定意味着你有泄漏;但在某些时候,如果GC流了,至少有一些应该被释放;如果这种情况从未发生过,那就是泄漏的症状;尝试强制GC查看活动实例的数量是否下降;如果没有,则很可能是你有泄漏。