醒着☆☆

H5 Laya Native Game

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

为什么使用对象池?

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

 

posted on 2012-01-30 17:25  醒着/☆☆  阅读(2269)  评论(0编辑  收藏  举报