Use um pool de objetos, sempre que possível.
Outra importante otimização é chamada pool de objetos e envolve a reutilização de objetos com o tempo. Você cria um número de objetos definido durante a inicialização do aplicativo e os armazena em um pool, como um objeto Array ou Vector. Quando terminar de usar um objeto, você o desativa para que deixe de consumir recursos de CPU e remove todas as referências mutuas. No entanto, você não define as referências como
null
, o que o qualificaria para a coleta de lixo. Você simplesmente coloca o objeto de volta no pool e o recupera quando precisar de um novo objeto.
Reutilizar objetos reduz a necessidade de instanciar objetos, o que pode ser dispendioso. Também reduz a chance de execução do coletor de lixo, o que poderia tornar seu aplicativo mais lento. O código a seguir ilustra a técnica de pool de objetos:
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;
}
}
}
A classe SpritePool cria um pool de novos objetos na inicialização do aplicativo. O método
getSprite()
retorna instâncias desses objetos e o método
disposeSprite()
as libera. O código permite que o pool cresça quando tiver sido completamente consumido. Também é possível criar um pool de tamanho fixo, onde novos objetos não seriam alocados quando o pool é exaurido. Tente evitar criar novos objetos em loops, se possível. Para obter mais informações, consulte
Liberação de memória
. O código a seguir usa a classe SpritePool para recuperar novas instâncias:
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 );
}
}
O código a seguir remove todos os objetos de exibição da lista de exibição quando o mouse é clicado e os reutiliza posteriormente para outra tarefa:
stage.addEventListener ( MouseEvent.CLICK, removeDots );
function removeDots ( e:MouseEvent ):void
{
while (container.numChildren > 0 )
SpritePool.disposeSprite (container.removeChildAt(0) as Sprite );
}
Nota:
O vetor do pool sempre faz referência a objetos Sprite. Se quiser remover o objeto completamente da memória, você precisa de um método
dispose()
na classe SpritePool que remova todas as referências restantes.