Frys ned och tina upp objekt med hjälp av händelserna
REMOVED_FROM_STAGE
och
ADDED_TO_STAGE
.
Om du vill optimera koden ska du alltid frysa och tina upp dina objekt. Det är viktigt för alla objekt att de kan frysas och tinas upp, men detta är speciellt viktigt för visningsobjekt. Även om visningsobjekten inte längre finns i visningslistan och väntar på att samlas in med skräpinsamlaren, kan de ändå använda kod som är processorintensiv. De kan till exempel fortfarande använda Event.ENTER_FRAME. Detta resulterar i att det är viktigt att frysa och tina upp objekt på ett korrekt sätt med händelserna
Event.REMOVED_FROM_STAGE
och
Event.ADDED_TO_STAGE
. I följande exempel visas en interaktion mellan ett filmklipp som spelas upp på scenen och tangentbordet:
// 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;
}
}
När du klickar på knappen Remove tas filmklippet bort från visningslistan.
// 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);
}
Trots att det tagits bort från visningslistan skickas händelsen
Event.ENTER_FRAME
från filmklippet. Filmklippet körs fortfarande men det återges inte. Du hanterar den här situationen korrekt genom avlyssna de rätta händelserna och ta bort händelseavlyssnare, för att på så sätt förhindra att processorkrävande kod kommer att köras:
// 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();
}
När du klickar på knappen Show startas filmklippet om, händelsen
Event.ENTER_FRAME
avlyssnas igen och tangentbordet kan användas för att kontrollera filmklippet.
Obs!
Om ett visningsobjekt tas bort från visningslistan är det inte säkert att objektet kommer att frysas om referensen anges som
null
sedan det tagits bort. Om skräpinsamlaren inte körs kommer objektet att fortsätta förbruka minne och processorkraft, trots att objektet inte längre visas. Om du vill vara säker på att objektet förbrukar minsta möjliga processorkraft, ska du se till att frysa det fullständigt när du tar bort det på visningslistan.
Från och med Flash Player 10 och AIR 1.5 finns även följande beteenden. Om spelhuvudet kommer till en tom bildruta fryses visningsobjektet automatiskt, även om du inte har implementerat något frysningsbeteende.
Frysningar också viktiga när du läser in fjärrinnehåll med klassen Loader. När du använde Loader-klassen i Flash Player 9 och AIT 1.0 var det nödvändigt att manuellt frysa innehållet genom att avlyssna händelsen
Event.UNLOAD
, som skickades av LoaderInfo-objektet. Varje händelse måste frysas manuellt, vilket inte alltid var en enkel uppgift. I Flash Player 10 och AIR 1.5 introducerades en viktig ny metod i klassen Loader, som kallas
unloadAndStop()
. Med denna metod kan du ta bort en SWF-fil, automatiskt frysa alla objekt i den inlästa SWF-filen och framtvinga körning av skräpinsamlaren.
I följande kod läses SWF-filen in och tas sedan bort med metoden
unload()
, vilket kräver mer bearbetning och manuell frysning:
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();
}
Det bästa sättet är att använda metoden
unloadAndStop()
, som hanterar frysning internt och som framtvingar att skräpinsamlingsprocessen körs:
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();
}
Följande åtgärder inträffar när metoden
unloadAndStop()
anropas:
-
Ljud stoppas.
-
Avlyssnare registrerade för SWF-filens huvudtidslinje tas bort.
-
Tidtagarobjekt stoppas.
-
Kringutrustning såsom kameror och mikrofoner frisläpps.
-
Alla filmklipp stoppas.
-
Utskick från
Event.ENTER_FRAME
,
Event.FRAME_CONSTRUCTED
,
Event.EXIT_FRAME
,
Event.ACTIVATE
och
Event.DEACTIVATE
stoppas.