Gebruik indien mogelijk objectpooling.
Een andere belangrijke optimalisatie is objectpooling, waarbij objecten worden hergebruikt. U maakt een bepaald aantal objecten tijdens de initialisatie van uw toepassing en slaat deze op in een pool, zoals een Array- of Vector-object. Wanneer u een object niet meer gebruikt, deactiveert u dit, zodat het geen CPU-bronnen meer verbruikt, en verwijdert u alle wederzijdse referenties. U stelt de verwijzingen echter niet in op
null
, anders zouden ze in aanmerking komen voor afvalophaling. U plaatst het object gewoon terug in de pool en haalt het op wanneer u een nieuw object nodig hebt.
Hergebruik van objecten betekent dat u objecten niet zo vaak hoeft te instantiëren, hetgeen een besparing oplevert. Het beperkt ook de kans dat de afvalophaling wordt uitgevoerd, die uw toepassing kan vertragen. De volgende code illustreert de techniek voor objectpooling:
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;
}
}
}
De SpritePool-klasse maakt een pool met nieuwe objecten tijdens de initialisatie van de toepassing. De
getSprite()
-methode retourneert instanties van deze objecten en ze worden door de
disposeSprite()
-methode vrijgegeven. Met de code kan de pool groeien, wanneer die volledig is gebruikt. U kunt ook een pool maken met een vaste omvang, waaraan nieuwe objecten niet worden toegewezen als de pool uitgeput is. Probeer indien mogelijk het maken van nieuwe objecten in loops te vermijden. Zie voor meer informatie
Geheugen vrijmaken
. De volgende code gebruikt de SpritePool-klasse om nieuwe instanties op te halen:
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 );
}
}
De volgende code verwijdert alle weergaveobjecten uit de weergavelijst wanneer er met de muis wordt geklikt en gebruikt ze later opnieuw voor een andere taak.
stage.addEventListener ( MouseEvent.CLICK, removeDots );
function removeDots ( e:MouseEvent ):void
{
while (container.numChildren > 0 )
SpritePool.disposeSprite (container.removeChildAt(0) as Sprite );
}
Opmerking:
De poolvector verwijst altijd naar de Sprite-objecten. Als u het object volledig uit het geheugen wilt verwijderen, hebt u een
dispose()
-methode nodig voor de SpritePool-klasse, die alle overgebleven referenties verwijdert.