一個好的Flash作品, 除了要有美美的設計與酷炫的動態外更重要的應該是效能。
就以一個EnterFrame事件來說明好了。
在ActionScript2.0時, MovieClip的EnterFrame事件, 當該MovieClip被移除時
其事件也會自動消失。
但在ActionScript3.0, 把該MoviecClip移除, EnterFrame還是會在。
所以當你載入越多的swf檔時, 沒有把前一個swf事件都移除的話, 效能就會越來越差。
那要如何移除事件呢?
那什麼時候要取消偵聽?
通常在移除可視物件時, 就要把所有的事件都取消掉, 這樣才不會一直佔住記憶體。
可視物件有個Event.REMOVE_FROM_STAGE可以加以利用
當物件被從stage移除時, 會廣播該事件。
當偵聽者聽到時, 就把所有有註冊的事件通通取消掉。
被載入的Loaded.swf
在建構函式時就偵聽Event.ENTER_FRAME事件。
載入的主要SWF
發怖成功後, 可以看到面版不斷的輸出文字,
按下按鈕 ,unload該swf, 還是看到面版不斷的輸出文字, 也就表示物件移除
不代表事件移除, 所以我們改寫一下Loaded.swf的程式碼。
這樣當物件被除掉後, 也可以一起把事件都取消掉
補充一下:
在google找了些相關資訊, 發現一種不正規的Hack方法
但真的能將記憶體給釋放:
經過不小心google一下
發現這樣的做法是一種不正規的Hack方法
但真的能清掉記憶體
試試看再補上一句
這樣能清的更乾淨
就以一個EnterFrame事件來說明好了。
在ActionScript2.0時, MovieClip的EnterFrame事件, 當該MovieClip被移除時
其事件也會自動消失。
但在ActionScript3.0, 把該MoviecClip移除, EnterFrame還是會在。
所以當你載入越多的swf檔時, 沒有把前一個swf事件都移除的話, 效能就會越來越差。
那要如何移除事件呢?
//偵聽
clip.addEventListener(事件類型:String , 偵聽者函式:Function)
//取消偵聽
clip.removeEventListener(事件類型:String , 偵聽者函式:Function);
那什麼時候要取消偵聽?
通常在移除可視物件時, 就要把所有的事件都取消掉, 這樣才不會一直佔住記憶體。
可視物件有個Event.REMOVE_FROM_STAGE可以加以利用
當物件被從stage移除時, 會廣播該事件。
當偵聽者聽到時, 就把所有有註冊的事件通通取消掉。
被載入的Loaded.swf
在建構函式時就偵聽Event.ENTER_FRAME事件。
package { import flash.display.Sprite; import flash.events.Event; public class Loaded extends Sprite{ public function Loaded() { this.addEventListener(Event.ENTER_FRAME, onEventEnterFrame); } private function onEventEnterFrame(e:Event):void { trace(e); } } }
載入的主要SWF
package { import com.bit101.components.PushButton; import flash.display.Loader; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.net.URLRequest; [SWF(width = "950", height = "500", frameRate = "41", backgroundColor = "#000000", pageTitle = "milkmidi.com")] public class Main extends Sprite{ private var _ldr:Loader public function Main() { _ldr = new Loader(); _ldr.load(new URLRequest("Loaded.swf")); this.addChild(_ldr); var _btn:PushButton = new PushButton(this, 0, 0, "unload", onClick); } private function onClick(e:MouseEvent):void{ _ldr.unload(); } } }
發怖成功後, 可以看到面版不斷的輸出文字,
按下按鈕 ,unload該swf, 還是看到面版不斷的輸出文字, 也就表示物件移除
不代表事件移除, 所以我們改寫一下Loaded.swf的程式碼。
package { import flash.display.Sprite; import flash.events.Event; public class Loaded extends Sprite{ public function Loaded() { this.addEventListener(Event.ADDED_TO_STAGE, onAdd2Stage); //當可視物件被加入至場景後, 會發出的事件。 this.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); //當可視物件被移除後至場景, 會發出的事件。 } private function onRemovedFromStage(e:Event):void { //物件被移除, 所有有偵聽的事件也要手動取消掉。 this.removeEventListener(Event.ADDED_TO_STAGE, onAdd2Stage); this.removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); this.removeEventListener(Event.ENTER_FRAME, onEventEnterFrame); } private function onAdd2Stage(e:Event):void { this.addEventListener(Event.ENTER_FRAME, onEventEnterFrame); } private function onEventEnterFrame(e:Event):void { trace(e); } } }
這樣當物件被除掉後, 也可以一起把事件都取消掉
補充一下:
在google找了些相關資訊, 發現一種不正規的Hack方法
但真的能將記憶體給釋放:
import flash.net.LocalConnection; import flash.system.System; try{ new LocalConnection().connect("foo"); new LocalConnection().connect("foo"); }catch(error : Error){ } //透過try catch,讓Player的garbage collection強製他回收不用的記憶體 System.gc(); //強制執行記憶體回收程序
經過不小心google一下
發現這樣的做法是一種不正規的Hack方法
但真的能清掉記憶體
試試看再補上一句
try{ new LocalConnection().connect("foo"); new LocalConnection().connect("foo"); }catch(error : Error){ } System.gc();
這樣能清的更乾淨
留言
張貼留言