为了可以让对象复用,防止大量重复创建对象,导致资源浪费,使用对象池来管理。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
 * 对象池
 * @author chenkai 2019.10.25
 */
class Pool {
    private static poolMap = {};
 
    /**
     * 根据签名获取对象
     * @param sign 签名
     * @param clz 类名,对象池空,则根据类名创建新对象
     */
    public static getItemBySign(sign:string,clz:any){
        let pool = (this.poolMap[sign] || (this.poolMap[sign] = []));
        if (pool.length) {
            return pool.pop();
        }
        let obj: any = new clz();
        obj.poolKey = sign;
        return obj;
    }
     
    /**
     * 获取对象
     * @param clz 对象类名
     * @param args
     */
    public static getItemByClass(clz: any) {
        let clzName = clz.prototype["__class__"];
        return this.getItemBySign(clzName, clz);
    }
 
    /**
     * 根据签名回收对象
     * @param sign 签名
     * @param ins 对象实例
     */
    public static recoverBySign(sign:string, ins:any){
        this.poolMap[sign] && this.poolMap[sign].push(ins);
    }
 
    /**
     * 回收对象
     * @param ins 对象实例
     */
    public static recoverByIns(ins: any) {
        this.recoverBySign(ins.poolKey, ins);
    }
 
    /**
     * 根据签名清理对象
     * @param sign 签名
     */
    public static clearBySign(sign:string){
        let pool = this.poolMap[sign];
        if(pool){
            let len = pool.length;
            for(let i=0;i<len;i++){
                pool[i].destroy && pool[i].destroy();
            }
            pool.length = 0;
            delete this.poolMap[sign];
        }
    }
 
    /**
     * 清理对象。对象会执行destroy。
     * @param clz 对象类名
     */
    public static clearByClass(clz: any) {
        let clzName = clz.prototype["__class__"];
        this.clearBySign(clzName);
    }
 
     
 
    /**清理所有对象 */
    public static clearAll(){
        for(let key in this.poolMap){
           this.clearBySign(key);
        }
    }
 
}

  

 

1
2
3
4
5
//获取一个Ball
let ball:Ball = Pool.getItemByClass(Ball);
 
//回收一个Ball
Pool.recoverByIns(ball);

 

 

以下是Laya的对象池源码,可以参考学习下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
*<p> <code>Pool</code> 是对象池类,用于对象的存贮、重复使用。</p>
*<p>合理使用对象池,可以有效减少对象创建的开销,避免频繁的垃圾回收,从而优化游戏流畅度。</p>
*/
//class laya.utils.Pool
var Pool=(function(){
    function Pool(){}
    __class(Pool,'laya.utils.Pool');
    Pool.getPoolBySign=function(sign){
        return Pool._poolDic[sign] || (Pool._poolDic[sign]=[]);
    }
  
    Pool.clearBySign=function(sign){
        if (Pool._poolDic[sign])Pool._poolDic[sign].length=0;
    }
  
    Pool.recover=function(sign,item){
        if (item["__InPool"])return;
        item["__InPool"]=true;
        Pool.getPoolBySign(sign).push(item);
    }
  
    Pool.getItemByClass=function(sign,cls){
        var pool=Pool.getPoolBySign(sign);
        var rst=pool.length ? pool.pop():new cls();
        rst["__InPool"]=false;
        return rst;
    }
  
    Pool.getItemByCreateFun=function(sign,createFun){
        var pool=Pool.getPoolBySign(sign);
        var rst=pool.length ? pool.pop():createFun();
        rst["__InPool"]=false;
        return rst;
    }
  
    Pool.getItem=function(sign){
        var pool=Pool.getPoolBySign(sign);
        var rst=pool.length ? pool.pop():null;
        if (rst){
            rst["__InPool"]=false;
        }
        return rst;
    }
  
    Pool._poolDic={};
    Pool.InPoolSign="__InPool";
    return Pool;
})()

  

 

posted on   gamedaybyday  阅读(3801)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示