Umieszczanie obiektów w puli

W miarę możliwości należy zawsze umieszczać obiekty w puli.

Inną istotną metodą optymalizacji jest umieszczanie obiektów w puli, co polega na ponownym wykorzystaniu tych samych obiektów w miarę upływu czasu. Należy utworzyć określoną liczbę obiektów podczas inicjowania aplikacji, a następnie zapisać je w puli, która będzie obiektem klasy Array lub Vector. Po zakończeniu pracy z obiektem należy go dezaktywować, dzięki czemu nie będzie on zużywał zasobów procesora, a także usunąć wszystkie odwołania wzajemne. Nie należy jednak ustawiać odwołań na null , ponieważ mogłoby to zakwalifikować obiekt do usunięcia w procesie czyszczenia pamięci. Wystarczy umieścić obiekt z powrotem w puli, a następnie pobrać go, gdy potrzebny będzie nowy obiekt.

Ponowne korzystanie z obiektów ogranicza potrzebę tworzenia instancji obiektów, co może być kosztowne. Ponadto ogranicza prawdopodobieństwo uruchomienia procesu czyszczenia pamięci, który może znacznie spowolnić aplikację. Poniższy kod prezentuje technikę umieszczania obiektów w puli.

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

Klasa SpritePool tworzy pulę nowych obiektów podczas inicjowania aplikacji. Metoda getSprite() zwraca instancje tych obiektów, a metoda disposeSprite() zwalnia je. Kod umożliwia powiększanie puli, gdy jej pojemność zostanie całkowicie wykorzystana. Możliwe jest także utworzenie puli o stałej wielkości — w takim przypadku całkowite wykorzystanie puli uniemożliwi dodawanie do niej nowych obiektów. W miarę możliwości należy unikać tworzenia nowych obiektów w pętlach. Więcej informacji zawiera sekcja Zwalnianie pamięci . W poniższym kodzie wykorzystano klasę SpritePool do pobierania nowych instancji:

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

Poniższy kod po kliknięciu przycisku myszy usuwa wszystkie obiekty wyświetlane z listy wyświetlania, a następnie wykorzystuje je ponownie dla innego zadania:

stage.addEventListener ( MouseEvent.CLICK, removeDots ); 
  
function removeDots ( e:MouseEvent ):void 
{ 
    while (container.numChildren > 0 ) 
        SpritePool.disposeSprite (container.removeChildAt(0) as Sprite ); 
}
Uwaga: Wektor puli zawsze odwołuje się do obiektów Sprite. Jeśli konieczne jest całkowite usunięcie obiektu z pamięci, wymagane jest użycie metody dispose() klasy SpritePool, która powoduje usunięcie wszystkich pozostałych odwołań.