使用
REMOVED_FROM_STAGE
和
ADDED_TO_STAGE
事件即可正確地凍結和取消凍結物件。
若要將程式碼最佳化,請凍結和取消凍結您的物件。凍結和取消凍結對於所有物件都很重要,但是對顯示物件尤為重要。即使顯示物件已不再顯示清單中,並等待記憶體回收,它們可能仍然正在使用消耗大量 CPU 的程式碼。例如,它們可能仍然持續使用 Event.ENTER_FRAME。因此,使用
Event.REMOVED_FROM_STAGE
和
Event.ADDED_TO_STAGE
事件正確地凍結與取消凍結物件非常重要。下列範例顯示在舞台中播放並與鍵盤互動的影片片段:
// Listen to keyboard events
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyIsDown);
stage.addEventListener(KeyboardEvent.KEY_UP, keyIsUp);
// Create object to store key states
var keys:Dictionary = new Dictionary(true);
function keyIsDown(e:KeyboardEvent):void
{
// Remember that the key was pressed
keys[e.keyCode] = true;
if (e.keyCode==Keyboard.LEFT || e.keyCode==Keyboard.RIGHT)
{
runningBoy.play();
}
}
function keyIsUp(e:KeyboardEvent):void
{
// Remember that the key was released
keys[e.keyCode] = false;
for each (var value:Boolean in keys)
if ( value ) return;
runningBoy.stop();
}
runningBoy.addEventListener(Event.ENTER_FRAME, handleMovement);
runningBoy.stop();
var currentState:Number = runningBoy.scaleX;
var speed:Number = 15;
function handleMovement(e:Event):void
{
if (keys[Keyboard.RIGHT])
{
e.currentTarget.x += speed;
e.currentTarget.scaleX = currentState;
} else if (keys[Keyboard.LEFT])
{
e.currentTarget.x -= speed;
e.currentTarget.scaleX = -currentState;
}
}
按一下「Remove」按鈕時,會從顯示清單移除影片片段:
// Show or remove running boy
showBtn.addEventListener (MouseEvent.CLICK,showIt);
removeBtn.addEventListener (MouseEvent.CLICK,removeIt);
function showIt (e:MouseEvent):void
{
addChild (runningBoy);
}
function removeIt(e:MouseEvent):void
{
if (contains(runningBoy)) removeChild(runningBoy);
}
即使已從顯示清單移除影片片段,影片片段仍然會傳送
Event.ENTER_FRAME
事件。影片片段仍然會執行,但是不會顯示。若要正確處理此情形,請偵聽正確的事件並移除事件偵聽程式,避免執行耗用 CPU 的程式碼:
// Listen to Event.ADDED_TO_STAGE and Event.REMOVED_FROM_STAGE
runningBoy.addEventListener(Event.ADDED_TO_STAGE,activate);
runningBoy.addEventListener(Event.REMOVED_FROM_STAGE,deactivate);
function activate(e:Event):void
{
// Restart everything
e.currentTarget.addEventListener(Event.ENTER_FRAME,handleMovement);
}
function deactivate(e:Event):void
{
// Freeze the running boy - consumes fewer CPU resources when not shown
e.currentTarget.removeEventListener(Event.ENTER_FRAME,handleMovement);
e.currentTarget.stop();
}
按下「Show」按鈕時,會重新啟動影片片段並再次監聽
Event.ENTER_FRAME
事件,而鍵盤會正確地控制影片片段。
備註:
如果從顯示清單移除顯示物件,並在移除之後將其參考設定為
null
,這樣並無法保證物件已被凍結。如果垃圾回收器未執行,即使不再顯示物件,該物件仍會繼續耗用記憶體與 CPU 處理。若要確保物件盡可能耗用最少的 CPU 處理,請確定物件從顯示清單移除後已被完全凍結。
從 Flash Player 10 與 AIR 1.5 開始,也會發生下列行為。如果播放磁頭遇到空白影格,就會自動凍結顯示物件,即使您未實作任何凍結行為。
使用 Loader 類別來載入遠端內容時,凍結的概念也非常重要。透過 Flash Player 9 與 AIR 1.0 使用 Loader 類別時,必須手動凍結內容,方法是偵聽 LoaderInfo 物件傳送的
Event.UNLOAD
事件。每個物件都必須手動凍結,這是不可忽略的工作。Flash Player 10 與 AIR 1.5 引進 Loader 類別的重要新方法,稱為
unloadAndStop()
。此方法可讓您取消載入 SWF 檔案、自動凍結已載入 SWF 檔案中的每個物件,以及強制執行垃圾回收器。
下列程式碼會載入 SWF 檔案,然後使用
unload()
方法來取消載入 SWF 檔案,但這將需要更多的處理與手動凍結:
var loader:Loader = new Loader();
loader.load ( new URLRequest ( "content.swf" ) );
addChild ( loader );
stage.addEventListener ( MouseEvent.CLICK, unloadSWF );
function unloadSWF ( e:MouseEvent ):void
{
// Unload the SWF file with no automatic object deactivation
// All deactivation must be processed manually
loader.unload();
}
最好的方法是使用
unloadAndStop()
方法,這會以原生方式處理凍結,並強制執行記憶體回收程序:
var loader:Loader = new Loader();
loader.load ( new URLRequest ( "content.swf" ) );
addChild ( loader );
stage.addEventListener ( MouseEvent.CLICK, unloadSWF );
function unloadSWF ( e:MouseEvent ):void
{
// Unload the SWF file with automatic object deactivation
// All deactivation is handled automatically
loader.unloadAndStop();
}
呼叫
unloadAndStop()
方法後,會發生下列動作: