类对象池设计

 对象池的字典

private Dictionary<int, Queue<object>> m_ClassObjectPoolDic;

在构造函数中初始化

        public ClassObjectPool()
        {
            ClassObjectCount = new Dictionary<int, byte>();
            m_ClassObjectPoolDic = new Dictionary<int, Queue<object>>();
        }

 从对象池中取出一个对象

        #region Dequeue 取出一个对象
        /// <summary>
        /// 取出一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T Dequeue<T>() where T : class, new()
        {
            lock (m_ClassObjectPoolDic)
            {
                //先找到这个类的哈希
                int key = typeof(T).GetHashCode();

                Queue<object> queue = null;
                m_ClassObjectPoolDic.TryGetValue(key, out queue);

                if (queue == null)
                {
                    queue = new Queue<object>();
                    m_ClassObjectPoolDic[key] = queue;
                }

                //开始获取对象
                if (queue.Count > 0)
                {
                    //说明队列中 有闲置的
                    //Debug.Log("对象 " + key + "存在 从池中获取");
                    object obj = queue.Dequeue();
#if UNITY_EDITOR
                    Type t = obj.GetType();
                    if (InspectorDic.ContainsKey(t))
                    {
                        InspectorDic[t]--;
                    }
                    else
                    {
                        InspectorDic[t] = 0;
                    }
#endif
                    return (T)obj;
                }
                else
                {
                    //如果队列中没有 才实例化一个
                    //Debug.Log("对象 " + key + "不存在 进行实例化");
                    return new T();
                }
            }
        }
        #endregion

 

对象回池

        #region Enqueue 对象回池
        /// <summary>
        /// 对象回池
        /// </summary>
        /// <param name="obj"></param>
        public void Enqueue(object obj)
        {
            lock (m_ClassObjectPoolDic)
            {
                int key = obj.GetType().GetHashCode();
                //Debug.Log("对象 " + key + "回池了");

                Queue<object> queue = null;
                m_ClassObjectPoolDic.TryGetValue(key, out queue);

#if UNITY_EDITOR
                Type t = obj.GetType();
                if (InspectorDic.ContainsKey(t))
                {
                    InspectorDic[t]++;
                }
                else
                {
                    InspectorDic[t] = 1;
                }
#endif

                if (queue != null)
                {
                    queue.Enqueue(obj);
                }
            }
        }
        #endregion

对象池的释放

        /// <summary>
        /// 释放类对象池
        /// </summary>
        public void Release()
        {
            lock (m_ClassObjectPoolDic)
            {
                int queueCount = 0; //队列的数量
                //1.定义迭代器
                var enumerator = m_ClassObjectPoolDic.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    int key = enumerator.Current.Key;
                    //拿到队列
                    Queue<object> queue = m_ClassObjectPoolDic[key];
#if UNITY_EDITOR
                    Type t = null;
#endif
                    queueCount = queue.Count;

                    //用户释放的时候 判断
                    byte resideCount = 0;
                    ClassObjectCount.TryGetValue(key, out resideCount);
                    while (queueCount > resideCount)
                    {
                        //队列中有可释放的对象
                        queueCount--;
                        object obj = queue.Dequeue(); //从队列中取出一个 这个对象没有任何引用,就变成了野指针 等待GC回收
#if UNITY_EDITOR
                        t = obj.GetType();
                        InspectorDic[t]--;
#endif
                    }

                    if (queueCount == 0)
                    {
#if UNITY_EDITOR
                        if (t != null)
                        {
                            InspectorDic.Remove(t);
                        }
#endif
                    }
                }
                //GC 整个项目中,有一处GC即可
                GC.Collect();
            }
        }

 完整代码

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace YouYou
{
    /// <summary>
    /// 类对象池
    /// </summary>
    public class ClassObjectPool : IDisposable
    {
        /// <summary>
        /// 类对象池字典
        /// </summary>
        private Dictionary<int, Queue<object>> m_ClassObjectPoolDic;
#if UNITY_EDITOR
        /// <summary>
        /// 在监视面板显示的信息
        /// </summary>
        public Dictionary<Type, int> InspectorDic = new Dictionary<Type, int>();
#endif
        /// <summary>
        /// 类对象在池中的常驻数量
        /// </summary>
        public Dictionary<int, byte> ClassObjectCount
        {
            get;
            private set;
        }
        public ClassObjectPool()
        {
            ClassObjectCount = new Dictionary<int, byte>();
            m_ClassObjectPoolDic = new Dictionary<int, Queue<object>>();
        }

        #region 设置类常驻数量
        /// <summary>
        /// 设置类常驻数量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="count"></param>
        public void SetResideCount<T>(byte count) where T : class
        {
            int key = typeof(T).GetHashCode();
            ClassObjectCount[key] = count;
        }
        #endregion

        #region Dequeue 取出一个对象
        /// <summary>
        /// 取出一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T Dequeue<T>() where T : class, new()
        {
            lock (m_ClassObjectPoolDic)
            {
                //先找到这个类的哈希
                int key = typeof(T).GetHashCode();

                Queue<object> queue = null;
                m_ClassObjectPoolDic.TryGetValue(key, out queue);

                if (queue == null)
                {
                    queue = new Queue<object>();
                    m_ClassObjectPoolDic[key] = queue;
                }

                //开始获取对象
                if (queue.Count > 0)
                {
                    //说明队列中 有闲置的
                    //Debug.Log("对象 " + key + "存在 从池中获取");
                    object obj = queue.Dequeue();
#if UNITY_EDITOR
                    Type t = obj.GetType();
                    if (InspectorDic.ContainsKey(t))
                    {
                        InspectorDic[t]--;
                    }
                    else
                    {
                        InspectorDic[t] = 0;
                    }
#endif
                    return (T)obj;
                }
                else
                {
                    //如果队列中没有 才实例化一个
                    //Debug.Log("对象 " + key + "不存在 进行实例化");
                    return new T();
                }
            }
        }
        #endregion

        #region Enqueue 对象回池
        /// <summary>
        /// 对象回池
        /// </summary>
        /// <param name="obj"></param>
        public void Enqueue(object obj)
        {
            lock (m_ClassObjectPoolDic)
            {
                int key = obj.GetType().GetHashCode();
                //Debug.Log("对象 " + key + "回池了");

                Queue<object> queue = null;
                m_ClassObjectPoolDic.TryGetValue(key, out queue);

#if UNITY_EDITOR
                Type t = obj.GetType();
                if (InspectorDic.ContainsKey(t))
                {
                    InspectorDic[t]++;
                }
                else
                {
                    InspectorDic[t] = 1;
                }
#endif

                if (queue != null)
                {
                    queue.Enqueue(obj);
                }
            }
        }
        #endregion

        /// <summary>
        /// 释放类对象池
        /// </summary>
        public void Release()
        {
            lock (m_ClassObjectPoolDic)
            {
                int queueCount = 0; //队列的数量
                //1.定义迭代器
                var enumerator = m_ClassObjectPoolDic.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    int key = enumerator.Current.Key;
                    //拿到队列
                    Queue<object> queue = m_ClassObjectPoolDic[key];
#if UNITY_EDITOR
                    Type t = null;
#endif
                    queueCount = queue.Count;

                    //用户释放的时候 判断
                    byte resideCount = 0;
                    ClassObjectCount.TryGetValue(key, out resideCount);
                    while (queueCount > resideCount)
                    {
                        //队列中有可释放的对象
                        queueCount--;
                        object obj = queue.Dequeue(); //从队列中取出一个 这个对象没有任何引用,就变成了野指针 等待GC回收
#if UNITY_EDITOR
                        t = obj.GetType();
                        InspectorDic[t]--;
#endif
                    }

                    if (queueCount == 0)
                    {
#if UNITY_EDITOR
                        if (t != null)
                        {
                            InspectorDic.Remove(t);
                        }
#endif
                    }
                }
                //GC 整个项目中,有一处GC即可
                GC.Collect();
            }
        }

        public void Dispose()
        {
            m_ClassObjectPoolDic.Clear();
        }
	}
}

猜你喜欢

转载自blog.csdn.net/qq_35647121/article/details/131047785