为什么使用对象池?
因为FLASH是托管的GC清理资源,具体什么时候清理只有GC知道,那么我们的游戏的性能就.........
例如:游戏里点击按钮会加载一张图片,再次点击图片,会销毁图片。
那么如果用户不停的点击,会执行不断的加载 显示 销毁。内存就会很难控制。
摘自Adobe的一段
http://help.adobe.com/zh_CN/as3/mobile/WS948100b6829bd5a6-19cd3c2412513c24bce-8000.html
请尽可能使用对象池。
另一个重要优化称为对象池,涉及到不断重复使用对象。在初始化应用程序期间创建一定数量的对象并将其存储在一个池中,
例如 Array 或 Vector 对象。对一个对象完成操作后,停用该对象以免它占用 CPU 资源,然后删除所有相互引用。然而,
不要将引用设置为 null,这将使它符合垃圾回收条件。只需将该对象放回到池中,在需要新对象时可以对其进行检索。
重用对象可减少实例化对象的需求,而实例化对象成本很高。还可以减少垃圾回收器运行的机会,从而提高应用程序运行速度。
使用了对象池后
我们会首先创建出需要的实例,并且把它扔进对象池objectPool
-
对象池应该是靠单例获取
- 开始时:初始化的时候直接给池子一定量的对象
- 使用时:从objectPool里borrow一个
- 归还时(释放):return它到objectPool中去
- 完全释放:池矢量始终引用 Sprite 对象。如果要从内存中完全删除对象,需要对 SpritePool 类使用dispose()方法,从而删除所有剩余引用。
- 所有的打算放到对象池的对象(显示对象 or 音频对象 等等)都需要继承自IPool接口
- IPool 接口需要实现:reset() dispose()
reset():重置对象的 这个很有必要的。当很多显示对象当return时候 都要被重置
重置需要做的:对已经填充的数据恢复默认,对动画状态回到默认状态。总之就是让其回到刚刚构造完时的样子
dispose():该接口主要是在彻底销毁对象池时 需要把对象池里的元素都销毁,每个元素可能会在dispose里执行以下
removeEventListener
BitmapData.dispose();
delete object
stopMovieOrSound
1:IPoolItem.as 接口类
package com.naiking.interfaces { /** * @author 醒着☆☆ */ public interface IPoolItem { function reset():void; function dispose():void; } }
2:ObjectPoolManager.as对象池管理类
package com.naiking.manager { import com.naiking.data.HashMap; import com.naiking.interfaces.IPoolItem; import flash.utils.getDefinitionByName; /** * ObjectPoolManager * @醒着☆☆ * */ public class ObjectPoolManager { //dictionary private var pools:HashMap=new HashMap(); /** * @param classType:ClassName String * @param maxSize */ public function initPool(classType:String,maxSize:int):void { //create all item by once trace("Created pool of "+classType); if(pools.containsKey(classType)) return; var itemAry:Array=[]; pools.add(classType,itemAry); var cls:Class=getDefinitionByName(classType) as Class; for(var i:int=0;i<maxSize;i++) { itemAry.push(new cls()); } } public function returnItem(classType:String,item:IPoolItem):void { if(!pools.containsKey(classType)) { throw new Error("Not find:"+classType+" pool"); return; } trace("Give back item:"+classType); item.reset(); (pools.getValue(classType) as Array).push(item); } /** *Get one item from pool * @param classType: * @return * */ public function borrowItem(classType:String):IPoolItem { if(!pools.containsKey(classType)) { throw new Error("Not find:"+classType+" pool"); return; } if((pools.getValue(classType) as Array).length==0) { throw new Error("The Pool:"+classType+" is full,Need expand"); return; } trace("Borrowed a item of"+classType); return (pools.getValue(classType) as Array).pop(); } public function disposePool(classType:String):void { if(!pools.containsKey(classType)) return; //clear pool var itemAry:Array=pools.getValue(classType) as Array; //dispose objects in pool for(var i:int=0;i<itemAry.length;i++) { /* the dispose() function is used to removeEventListener、dispose Bitmapdata、delete dynamic property */ (itemAry[i] as IPoolItem).dispose(); } itemAry=null; //remove this key from dictionary pools.remove(classType); } public function ObjectPoolManager(_sig:Sig) { } private static var _instance:ObjectPoolManager; public static function getInstance():ObjectPoolManager { if(!_instance) _instance=new ObjectPoolManager(new Sig()); return _instance; } } } final class Sig{}
3:HashMap.as 基本哈希表
package com.naiking.data { import flash.utils.Dictionary; /** * 哈希图 * @author 醒着☆☆ * */ public class HashMap { private var _length:int; private var _content:Dictionary; private var _weakKeys:Boolean; /** * 构造函数 * @param weakKeys 是否是弱引用 * */ public function HashMap(weakKeys:Boolean = false) { _weakKeys = weakKeys; _length = 0; _content = new Dictionary(weakKeys); } /** * 当前HashMap的长度 * @return * */ public function get length():int { return _length; } /** * 当前HashMap是否为空 * @return * */ public function isEmpty():Boolean { return _length == 0; } /** * 获取Key列表 * @return * */ public function getKeys():Array { var temp:Array = new Array(_length); var index:int = 0; var i:*; for(i in _content) { temp[index] = i; index++; } return temp; } /** * 获取Value列表 * @return * */ public function getValues():Array { var temp:Array = new Array(_length); var index:int = 0; var i:*; for each(i in _content) { temp[index] = i; index++; } return temp; } /** * 对Key列表中的每一项执行函数 * @param func * */ public function eachKey(func:Function):void { var i:*; for(i in _content) { func(i); } } /** * 对Value列表中的每一项执行函数 * @param func * */ public function eachValue(func:Function):void { var i:*; for each(i in _content) { func(i); } } /** * 对整个HashMap的每一项执行函数 * @param func 第一个参数是key,第二个参数是Value * */ public function each2(func:Function):void { var i:*; for(i in _content) { func(i,_content[i]); } } /** * 当前HashMap是否有value * @param value * @return * */ public function containsValue(value:*):Boolean { var i:*; for each(i in _content) { if (i === value) { return true; } } return false; } /** * 对HashMap中的每一项执行测试函数,直到获得返回 true 的项。 * @param func 第一个参数是key,第二个参数是Value * @return * */ public function some(func:Function):Boolean { var i:*; for(i in _content) { if(func(i,_content[i])) { return true; } } return false; } /** * 对HashMap中的每一项执行测试函数,并构造一个新数组(值,不包含Key),其中的所有项都对指定的函数返回 true。 如果某项返回 false,则新数组中将不包含此项。 * @param func 第一个参数是key,第二个参数是Value * @return * */ public function filter(func:Function):Array { var arr:Array = []; var i:*; var v:*; for(i in _content) { v = _content[i]; if(func(i,v)) { arr.push(v); } } return arr; } /** * 当前HashMap是否有Key * @param key * @return * */ public function containsKey(key:*):Boolean { if (_content[key] === undefined) { return false; } return true; } /** * 从指定的Key中获取 Value * @param key * @return * */ public function getValue(key:*):* { var value:* = _content[key]; return value === undefined ? null : value; } /** * 从指定的Value中获取Key * @param value * @return * */ public function getKey(value:*):* { var i:*; for(i in _content) { if(_content[i] == value) { return i; } } return null; } /** * 添加key value,返回的是旧的key对应的value,如果没有则返回null * @param key * @param value * @return * */ public function add(key:*, value:*):* { if (key == null) { throw new ArgumentError("cannot put a value with undefined or null key!"); return null; } if(value === undefined) { return null; } else { if (_content[key] === undefined) { _length++; } var oldValue:* = getValue(key); _content[key] = value; return oldValue; } } /** * 移除key value,返回的是旧的key对应的value,如果没有则返回null * @param key * @return * */ public function remove(key:*):* { if (_content[key] === undefined) { return null; } var temp:* = _content[key]; delete _content[key]; _length--; return temp; } /** * 清空当前HashMap * */ public function clear():void { _length = 0; _content = new Dictionary(_weakKeys); } /** * 克隆当前 HashMap * @return * */ public function clone():HashMap { var temp:HashMap = new HashMap(_weakKeys); var i:*; for(i in _content) { temp.add(i, _content[i]); } return temp; } public function toString():String { var ks:Array = getKeys(); var vs:Array = getValues(); var len:int = ks.length; var temp:String = "HashMap Content:\n"; var i:int; for(i = 0; i < len; i++) { temp += ks[i] + " -> " + vs[i] + "\n"; } return temp; } } }