通用框架(四)对象池

废话不多说先上流程图

目前项目里面大多数用的对象池一般都是类对象池或者物体对象池

我参加的面试里面经常会问到如何去优化string的问题,string了几次创建了多少个对象,我们一般通常做法就是用stringbuilder来优化,它其实本身也是一个类,每一次用的时候也得new,如果用多的话也new的特别多,那么类的对象池在这里就用的特别多了。

对象池的思想就是预先创建,提供初始化接口,有创建好的调用初始化就直接用,没有的话我再去创建。

类的对象池

在这里每个类对象区分我用的是hash码来识别,而这个类我用Queue队列去存储

key为hashcode,value用队列去存储;

作为一个池那么他需要提供出来(dequeue)和进去(enqueue)接口!

出池
入池

这两个接口写完之后,我们需要考虑如何释放,那么在提供一个clear清空接口,在切换场景时或者其他需要释放时调用。

释放类对象池代码

到这里三个接口就写完了,但是类对象不如物体对象能够直接到看到,类对象在内存里看不到,我们需要把它在编辑器上能够显示出来。

创建Editor文件下,在文件夹下创建PoolEditor显示脚本;

这个太长了,我就不截图了,直接上代码。

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

namespace JIANING
{
    [CustomEditor(typeof(PoolComponent), true)]
    public class PoolComponentInsprctor : Editor
    {
        //释放间隔属性
        private SerializedProperty m_ClearInterval = null;

        //释放间隔属性
        private SerializedProperty m_GameObjectPoolGroups = null;

        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            PoolComponent component = base.target as PoolComponent;

            int clearInterval = (int)EditorGUILayout.Slider("清空类对象池间隔", m_ClearInterval.intValue, 10, 1800);
            if (clearInterval != m_ClearInterval.intValue)
            {
                component.m_ClearInterval = clearInterval;
            }
            else
            {
                m_ClearInterval.intValue = clearInterval;
            }


            GUILayout.BeginHorizontal("box");
            GUILayout.Label("类名");
            GUILayout.Label("池中数量", GUILayout.Width(50));
            GUILayout.Label("常驻数量", GUILayout.Width(50));
            GUILayout.EndHorizontal();

            if (component != null
                && component.PoolManager != null
                )
            {
                foreach (var item in component.PoolManager.ClassObjectPool.InspectorDic)
                {
                    GUILayout.BeginHorizontal("box");
                    GUILayout.Label(item.Key.Name);
                    GUILayout.Label(item.Value.ToString(), GUILayout.Width(50));

                    int key = item.Key.GetHashCode();
                    byte resideCount;
                    component.PoolManager.ClassObjectPool.ClassObjectCount.TryGetValue(key, out resideCount);

                    GUILayout.Label(resideCount.ToString(), GUILayout.Width(50));
                    GUILayout.EndHorizontal();
                }
            }

           

            EditorGUILayout.PropertyField(m_GameObjectPoolGroups,true);


            serializedObject.ApplyModifiedProperties();
            //重绘
            Repaint();

        }

        private void OnEnable()
        {
            //建立属性关系
            m_ClearInterval = serializedObject.FindProperty("m_ClearInterval");
            m_GameObjectPoolGroups = serializedObject.FindProperty("m_GameObjectPoolGroups");

            serializedObject.ApplyModifiedProperties();
        }


    }
}
编辑器显示当前类对象池

游戏物体对象池

游戏物体对象池我们利用PoolManager插件,然后进行封装为我们想要的;

这里我们用byte作为池的key,因为一个项目也不可能用成百上千的池对象。

创建pool实体类 规范参数
回池 入池接口

游戏物体对象和类对象思想上相同,但是在处理上面不同。

到这里对象池组件就写完了,具体代码可访问github。

留下评论

邮箱地址不会被公开。 必填项已用*标注