对象池

来源:互联网 发布:软件应用中心 编辑:程序博客网 时间:2024/06/03 16:01
请尽可能使用对象池。
另一个重要优化称为对象池,涉及到不断重复使用对象。在初始化应用程序期间创建一定数量的对象并将其存储在一个池中,例如 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() 方法,从而删除所有剩余引用。
原创粉丝点击