物件集區

盡可能使用物件集區。

另一項重要的最佳化稱為物件集區,它需要隨著時間重複使用物件。您可以在應用程式初始化期間建立定義的物件數目,並將它們儲存在集區中,例如 Array 或 Vector 物件。物件使用完畢後請停用物件,如此才不會耗用 CPU 資源,並請移除所有相互參考。不過,請勿將參考設定為 null,這樣會讓物件進行記憶體回收。您只要將物件放回集區,並在需要新物件時擷取它。

重複使用物件可降低實體化物件的需要,實體化物件會耗費大量資源成本。它也會降低垃圾回收器執行的機會,這將會導致應用程式變慢。下列程式碼說明物件集區技術:

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

SpritePool 類別會在應用程式初始化時建立新物件的集區。getSprite() 方法會傳回這些物件的實體,而 disposeSprite() 方法則會釋放它們。此程式碼會在完全耗用完集區後,讓集區成長。它也可以建立固定大小的集區,這樣在耗用完集區時,便不會配置新物件。請盡可能嘗試避免在迴圈中建立新物件。如需詳細資訊,請參閱釋放記憶體。下列程式碼使用 SpritePool 類別來擷取新實體:

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

下列程式碼會在按一下滑鼠時,從顯示清單移除所有的顯示物件,並稍後在其他工作重複使用它們。

stage.addEventListener ( MouseEvent.CLICK, removeDots ); 
  
function removeDots ( e:MouseEvent ):void 
{ 
    while (container.numChildren > 0 ) 
        SpritePool.disposeSprite (container.removeChildAt(0) as Sprite ); 
}
備註: 集區向量永遠都會參考 Sprite 物件。如果您要從記憶體完全移除物件,需要 SpritePool 類別的 dispose() 方法,這個方法將會移除所有剩餘的參考。