Pooling di oggetti

Usate il pooling degli oggetti quando potete.

Un'altra importante tecnica di ottimizzazione è il "pooling degli oggetti" e prevede il riutilizzo degli oggetti nel tempo. Durante l'inizializzazione della vostra applicazione, dovete creare un numero definito di oggetti e memorizzarli in un "pool", ad esempio un oggetto Array o Vector. Quando avete finito di utilizzare un oggetto, lo disattivate in modo che non consumi risorse della CPU e rimuovete tutti i riferimenti reciproci. Tuttavia, non impostate i riferimenti su null , per non rendere idoneo l'oggetto al processo di garbage collection. Limitatevi a reinserire l'oggetto nel pool, in modo da poterlo recuperare quando avete bisogno di un nuovo oggetto.

Riutilizzando gli oggetti è possibile ridurre la necessità di crearne nuove istanze, attività che può rivelarsi onerosa. Inoltre, si riducono le probabilità di esecuzione del processo di garbage collection, che può rallentare l'applicazione. Il codice riportato di seguito illustra la tecnica di pooling degli oggetti:

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; 
        } 
    } 
}

La classe SpritePool crea un pool di nuovi oggetti durante l'inizializzazione dell'applicazione. Il metodo getSprite() restituisce le istanze di questi oggetti e il metodo disposeSprite() le rilascia. Il codice consente al pool di crescere dopo che è stato consumato completamente. È anche possibile creare un pool di dimensioni fisse nel quale non vengano allocati nuovi oggetti quando il pool è esaurito. Cercate di evitare di creare nuovi oggetti, quando potete. Per ulteriori informazioni, vedete Liberare spazio in memoria . Il codice seguente utilizza la classe SpritePool per recuperare nuove istanze:

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 ); 
    } 
}

Il codice seguente rimuove tutti gli oggetti di visualizzazione dall'elenco di visualizzazione quando viene fatto clic sul mouse e li riutilizza in seguito per un'altra operazione:

stage.addEventListener ( MouseEvent.CLICK, removeDots ); 
  
function removeDots ( e:MouseEvent ):void 
{ 
    while (container.numChildren > 0 ) 
        SpritePool.disposeSprite (container.removeChildAt(0) as Sprite ); 
}
Nota: il vettore del pool fa sempre riferimento agli oggetti Sprite. Se volete rimuovere completamente l'oggetto dalla memoria, dovete utilizzare il metodo dispose() sulla classe SpritePool per eliminare tutti i riferimenti rimanenti.