AS3 Air桌面应用:已卸载SWF内部AS3代码仍执行的问题咨询
问题解答:SWF卸载后Timer仍运行是代码遗漏,并非特性
这不是AS3/AIR的默认特性,是你在卸载流程中遗漏了对SWF内部活动对象的清理步骤导致的。
核心原因
SWF的Event.UNLOAD事件触发,仅代表它的显示对象已从显示列表中移除,但内存中那些非显示类的活动对象(比如Timer、SoundChannel、Socket、EnterFrame事件监听等),只要还持有有效引用、没有被主动停止,就会继续在Flash Player的事件循环中运行,不受显示对象卸载的影响。
解决步骤
你需要从两个层面做处理,确保彻底终止SWF的所有代码执行:
1. 在swfA内部实现主动清理逻辑
给swfA添加一个公开的清理方法,专门用来停止内部的Timer、移除事件监听、置空引用:
var timer: Timer = new Timer(1000, 60); timer.addEventListener(TimerEvent.TIMER, onTick); timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimeUp); timer.start(); // 新增公开的清理方法 public function cleanup():void { if(timer) { timer.stop(); timer.removeEventListener(TimerEvent.TIMER, onTick); timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimeUp); timer = null; } // 若有其他活动对象(比如Sound、网络请求、EnterFrame监听),也要在这里同步清理 } function onTick(e:TimerEvent):void { trace("timer tick"); } function onTimeUp(e:TimerEvent):void { trace("timer complete"); }
2. 在MAIN端卸载前先调用清理方法,再用unloadAndStop替代unload
不要直接调用普通的unload(),改用unloadAndStop(true),它会强制停止SWF的时间线、Timer、声音等,同时配合主动调用swfA的清理方法,双重保障:
swfLoader.load(new URLRequest("swfA")); swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,onSwfLoad); swfLoader.contentLoaderInfo.addEventListener(Event.UNLOAD, onSwfUnload); function onSwfLoad(e:Event):void { trace("swfA loaded"); } function onSwfUnload(e:Event):void { trace("swfA unloaded"); } // 触发卸载的逻辑示例 function unloadSwfA():void { // 先调用swfA的清理方法 var swfAContent:MovieClip = swfLoader.content as MovieClip; if(swfAContent && swfAContent.hasOwnProperty("cleanup")) { swfAContent.cleanup(); } // 用unloadAndStop彻底终止SWF swfLoader.unloadAndStop(true); swfLoader.content = null; }
关键误区提醒
- 不要把
Event.UNLOAD等同于“SWF所有资源已被完全回收”,它只是显示层面的卸载通知。 - 非显示类的活动对象必须主动停止/清理,否则会持续占用内存并执行代码,导致内存泄漏。
内容的提问来源于stack exchange,提问作者FlashV8
相关产品推荐
相关产品推荐

