unity 对象池

来源:互联网 发布:三国志13 mac版修改器 编辑:程序博客网 时间:2024/05/12 16:03


对象池背后的理念其实是非常简单的。我们将对象存储在一个池子中,当需要时在再次使用,而不是每次都实例化一个新的对象。池的最重要的特性,也就是对象池设计模式的本质是允许我们获取一个“新的”对象而不管它真的是一个新的对象还是循环使用的对象。

这是网上找的解释。
我们游戏中大量用到了对象池。
今天看了下对象池底层的代码。下面这篇文章写得挺好
http://www.cnblogs.com/mezero/p/3955130.html
废话不多说,上我们自己的对象池代码。

using System;using UnityEngine;using System.Collections;using System.Collections.Generic;// 清0操作由调用者负责编写// 提供对非unity对象的缓存,即逻辑对象缓存// 注意必须是class哈// 提供接口 IObjectClear, Release时自动调用public interface IObjectClear{    void Clear();}public class ObjectPool{    class ObjectGroup    {        public Stack<object> m_freeStack;        public int m_iMaxNum;  // 最大数量,为0表示不限制,否则超过最大数量,Release时直接delete        public ObjectGroup()        {            m_freeStack = new Stack<object>();            m_iMaxNum = 0;        }    }       Dictionary< Type,   ObjectGroup > m_typeDic;    object m_locker = new object();    bool m_bIsthreadSafe;    public ObjectPool(bool bIsthreadSafe = false)    {        m_typeDic = new Dictionary< Type,   ObjectGroup >();        m_bIsthreadSafe = bIsthreadSafe;    }    public void Register<T>( int iInitNum, int iMaxNum = 0 ) where T : class, new()    {        if (iInitNum < 0)        {            throw new ArgumentException("Init num < 0");        }        ObjectGroup group = null;        if ( m_typeDic.TryGetValue(typeof(T), out group) )        {            // 已存在            return;        }        group = new ObjectGroup();        group.m_iMaxNum = iMaxNum;        if (iInitNum > 0)        {            for (int i = 0; i < iInitNum; i++)            {                T obj = new T();                if (m_bIsthreadSafe)                {                    lock (m_locker)                    {                        group.m_freeStack.Push(obj);                    }                }                else                {                    group.m_freeStack.Push(obj);                }            }        }        m_typeDic[typeof(T)] = group;    }    public T Get<T>() where T : class, new()    {        ObjectGroup group = null;        if (!m_typeDic.TryGetValue(typeof(T), out group))        {            Register<T>(1);            return Get<T>();        }        T obj = null;        if (0 == group.m_freeStack.Count)        {            obj = new T();        }else         {            if (m_bIsthreadSafe)            {                lock (m_locker)                {                    obj = group.m_freeStack.Pop() as T;                }            }            else            {                obj = group.m_freeStack.Pop() as T;            }        }        return obj;    }    public void Release<T>(T obj) where T : class, new()    {        if (null == obj)        {            throw new ArgumentException("obj is null!!");        }        ObjectGroup group = null;        Type t = ((object)obj).GetType();        if (!m_typeDic.TryGetValue(t, out group))        {            throw new ArgumentException("obj's type is not registered!");        }        if (obj is IObjectClear)        {            ((IObjectClear)obj).Clear();        }        if (group.m_iMaxNum > 0 && group.m_freeStack.Count >= group.m_iMaxNum)        {            if (obj is IDisposable)            {                ((IDisposable)obj).Dispose();             }            obj = null;            System.GC.Collect();        }        else        {            // add to free list            if (m_bIsthreadSafe)            {                lock (m_locker)                {                    group.m_freeStack.Push(obj);                }            }            else            {                group.m_freeStack.Push(obj);            }        }    }    private void _DestroyGroup( ObjectGroup group )    {        object obj = null;        while (group.m_freeStack.Count > 0)        {            if (m_bIsthreadSafe)            {                lock (m_locker)                {                    obj = group.m_freeStack.Pop();                }            }            else            {                obj = group.m_freeStack.Pop();            }            if (obj is IDisposable)            {                ((IDisposable)obj).Dispose();            }            obj = null;        }        if (m_bIsthreadSafe)        {            lock (m_locker)            {                group.m_freeStack.Clear();            }        }        else        {            group.m_freeStack.Clear();        }    }    public void DestroyType<T>() where T : class, new()    {        ObjectGroup group = null;        if (!m_typeDic.TryGetValue(typeof(T), out group))        {            throw new ArgumentException("obj's type is not registered!");        }        this._DestroyGroup(group);    }    // destroy所有实列    public void DestroyAll()    {        foreach (var it in m_typeDic)        {            ObjectGroup group = it.Value;            this._DestroyGroup(group);            group = null;        }        m_typeDic.Clear();               System.GC.Collect();    }}

0 0