GameFramework中的对象池ObjectPool
类图
使用
有2种对象池:
-
ReferencePool
简单对象池
对象从 IReference 派生,获取时没有会自动创建,放入后缓存住
如果你只是想简单创建和释放对象,就用这个// 定义要缓存的对象,从 IReference 派生 public class LoadBinaryInfo : IReference { public void Clear() { } } LoadBinaryInfo info = ReferencePool.Acquire<LoadBinaryInfo>(); // 从缓存池获取对象 ReferencePool.Release(info); // 放回缓存池中 ReferencePool.Add<LoadBinaryInfo>(10); // 可以先批量创建,效率更高 ReferencePool.Remove<LoadBinaryInfo>(10); // 可以批量删除,释放内存 ReferencePool.RemoveAll<LoadBinaryInfo>();
-
ObjectPool
复杂对象池
对象从 ObjectBase 派生,获取时没有返回null,必须自己创建
这个对象池的重点是管理已有对象,比如设置自动释放,容量上限,超时时间,释放优先级,加锁
如果你想设置对象自动释放等,就用这个,可以配合 ReferencePool 来创建对象// 实际要缓存的对象 public class HPBarItem : MonoBehaviour {} // 定义一个包装类,用来包装一个对象然后可以放到对象池中 // 必须从 ObjectBase 派生,用来把 HPBarItem 包装成可以放到对象池中的对象 // 要注意,对象池并不创建对象,需要你自己创建并添加,最常用 ReferencePool.Acquire 来创建包装类 public class HPBarItemObject : ObjectBase { // 创建可放入对象池的包装对象 public static HPBarItemObject Create(HPBarItem target) { HPBarItemObject hpBarItemObject = ReferencePool.Acquire<HPBarItemObject>(); hpBarItemObject.Initialize(target); return hpBarItemObject; } // 释放实际对象 protected override void Release(bool isShutdown) { HPBarItem hpBarItem = (HPBarItem)Target; if (hpBarItem == null) { return; } Object.Destroy(hpBarItem.gameObject); } } // 创建对象池,SingleSpwan 表示同名对象只能有一个 IObjectPool<HPBarItemObject> m_HPBarItemObjectPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool<HPBarItemObject>("HPBarItem", m_InstancePoolCapacity); // 从对象池获得对象 HPBarItemObject hpBarItemObject = m_HPBarItemObjectPool.Spawn(); if (hpBarItemObject != null) { // 取出实际对象 hpBarItem = (HPBarItem)hpBarItemObject.Target; } else { // 没有的话要自己创建 HPBarItem hpBarItem = Instantiate(m_HPBarItemTemplate); // 创建一个包装类,然后放到对象池 m_HPBarItemObjectPool.Register(HPBarItemObject.Create(hpBarItem), true); } // 使用对象 hpBarItem // 用完放回对象池,可以是实际对象,也可以是包装对象 m_HPBarItemObjectPool.Unspawn(hpBarItem); // 从对象池中释放,必须先放回对象池 m_HPBarItemObjectPool.ReleaseObject(hpBarItem);
代码分析
// Type 必须是 ObjectBase 的派生类
// CreateSingleSpawnObjectPool 和 CreateMultiSpawnObjectPool 的区别是:
// 调用 T ojb = objectPool.Spawn(name) 时,SingleSpawn 如果已经存在该名称对象,则返回 null
ObjectPoolManager.CreateSingleSpawnObjectPool(Type objectType, float expireTime)
{
return InternalCreateObjectPool(objectType, string.Empty, false, expireTime, DefaultCapacity, expireTime, DefaultPriority)
{
if (!typeof(ObjectBase).IsAssignableFrom(objectType))
{
throw new GameFrameworkException(Utility.Text.Format("Object type '{0}' is invalid.", objectType.FullName));
}
// 创建 ObjectPool<T>
Type objectPoolType = typeof(ObjectPool<>).MakeGenericType(objectType);
ObjectPoolBase objectPool = (ObjectPoolBase)Activator.CreateInstance(objectPoolType, name, allowMultiSpawn, autoReleaseInterval, capacity, expireTime, priority);
m_ObjectPools.Add(typeNamePair, objectPool);
return objectPool;
}
}