Verwenden Sie nach Möglichkeit Objektpools.
Eine weitere wichtige Optimierungsmethode ist die Verwendung von Objektpools, die die Wiederverwendung von Objekten ermöglichen. Während der Initialisierung der Anwendung erstellen Sie eine definierte Anzahl an Objekten, die in einem Pool gespeichert werden, wie beispielsweise ein Array- oder ein Vector-Objekt. Wenn ein Objekt nicht mehr benötigt wird, deaktivieren Sie es, damit es keine CPU-Ressourcen belegt. Außerdem entfernen Sie alle gegenseitigen Verweise. Sie stellen die Verweise jedoch nicht auf
null
ein, wodurch sie bei der Speicherbereinigung berücksichtigt würden. Sie verschieben das Objekt lediglich zurück in den Pool und rufen es wieder ab, wenn Sie ein neues Objekt benötigen.
Durch die Wiederverwendung von Objekten müssen Objekte weniger häufig instanziiert werden, was zahlreiche Ressourcen beanspruchen kann. Außerdem verringert sich die Wahrscheinlichkeit, dass die Speicherbereinigung ausgeführt wird, die sich ebenfalls negativ auf die Anwendungsgeschwindigkeit auswirken würde. Der folgende Code veranschaulicht die Verwendung von Objektpools:
package
{
import flash.display.Sprite;
public final class SpritePool
{
private static var MAX_VALUE:uint;
private static var GROWTH_VALUE:uint;
private static var counter:uint;
private static var pool:Vector.<Sprite>;
private static var currentSprite:Sprite;
public static function initialize( maxPoolSize:uint, growthValue:uint ):void
{
MAX_VALUE = maxPoolSize;
GROWTH_VALUE = growthValue;
counter = maxPoolSize;
var i:uint = maxPoolSize;
pool = new Vector.<Sprite>(MAX_VALUE);
while( --i > -1 )
pool[i] = new Sprite();
}
public static function getSprite():Sprite
{
if ( counter > 0 )
return currentSprite = pool[--counter];
var i:uint = GROWTH_VALUE;
while( --i > -1 )
pool.unshift ( new Sprite() );
counter = GROWTH_VALUE;
return getSprite();
}
public static function disposeSprite(disposedSprite:Sprite):void
{
pool[counter++] = disposedSprite;
}
}
}
Die SpritePool-Klasse erstellt bei der Initialisierung der Anwendung einen Pool mit neuen Objekten. Die
getSprite()
-Methode gibt Instanzen dieser Objekte zurück und die
disposeSprite()
-Methode gibt sie frei. Der Code bietet dem Pool die Möglichkeit, bei Bedarf zu wachsen. Es ist auch möglich, einen Pool mit einer festen Größe zu erstellen; in diesem Fall werden keine neuen Objekte zugewiesen, wenn der Pool erschöpft ist. Vermeiden Sie nach Möglichkeit, neue Objekte in Schleifen zu erstellen. Weitere Informationen finden Sie unter
Freigeben von Arbeitsspeicher
. Im folgenden Code wird die SpritePool-Klasse zum Abrufen neuer Instanzen verwendet:
const MAX_SPRITES:uint = 100;
const GROWTH_VALUE:uint = MAX_SPRITES >> 1;
const MAX_NUM:uint = 10;
SpritePool.initialize ( MAX_SPRITES, GROWTH_VALUE );
var currentSprite:Sprite;
var container:Sprite = SpritePool.getSprite();
addChild ( container );
for ( var i:int = 0; i< MAX_NUM; i++ )
{
for ( var j:int = 0; j< MAX_NUM; j++ )
{
currentSprite = SpritePool.getSprite();
currentSprite.graphics.beginFill ( 0x990000 );
currentSprite.graphics.drawCircle ( 10, 10, 10 );
currentSprite.x = j * (currentSprite.width + 5);
currentSprite.y = i * (currentSprite.width + 5);
container.addChild ( currentSprite );
}
}
Der folgende Code entfernt beim Klicken mit der Maus alle Anzeigeobjekte aus der Anzeigeliste und verwendet sie später für eine andere Aufgabe wieder:
stage.addEventListener ( MouseEvent.CLICK, removeDots );
function removeDots ( e:MouseEvent ):void
{
while (container.numChildren > 0 )
SpritePool.disposeSprite (container.removeChildAt(0) as Sprite );
}
Hinweis:
Der Pool-Vektor verweist immer auf die Sprite-Objekte. Wenn Sie das Objekt vollständig aus dem Arbeitsspeicher entfernen möchten, müssen Sie eine
dispose()
-Methode für die SpritePool-Klasse angeben, wodurch alle verbleibenden Verweise entfernt werden.