
Unity-简易对象池
在Unity中我们经常会用到对象池,使用对象池无非就是解决两个问题: 一是减少 new 时候寻址造成的消耗,该消耗的原因是内存碎片。 二是减少 Object.Instantiate 时内部进行序列化和反序列化而造成的CPU消耗。 设计: 从字面上理解对象池,池的意思就是容器。我们可以从池中获取一个对象(一条鱼),也可以向池中放入一个对象(一条鱼)。获取的操作我们叫Allocate(分配),而放入一个对象我们叫Recycle(回收)。所以我们可以定义池的接口为如下: public interface IPool<T> { T Allocate(); bool Recycle(T obj); } 为什么要用泛型呢?如何实现一个精简并且灵活的对象池。这个灵活很大一部分是通过泛型体现的。 池是容器的意思,在C#中可以是List,Queue或者Stack甚至是数组。所以对象池本身要维护一个容器。本篇我们选取Stack来作为池容器,原因是当我们在Allocate和Recycle时并不关心缓存的存储的顺序,只要求缓存对象的地址是连续的。代码如下所示: using System.Collections.Generic; public abstract class Pool<T> : IPool<T> { ... protected Stack<T> mCacheStack = new Stack<T>(); ... } Pool是个抽象类,实现一个精简并且灵活的对象池。这个灵活很大一部分是通过抽象类体现的。 现在对象的存取和缓存接口都设计好了,那么这些对象是从哪里来的呢?我们分析下,创建对象我们知道有两种方式,反射构造方法和new一个对象。对象池的一个重要功能就是缓存,要想实现缓存就要求对象可以在对象池内部进行创建。所以我们要抽象出一个对象的工厂,代码如下所示: public interface IObjectFactory<T> { T Create(); } 为什么要用工厂? 实现一个精简并且灵活的对象池。这个灵活很大一部分是通过工厂体现的。 OK,现在对象的创建,存取,缓存的接口都设计好了。下面放出Pool的全部代码。 using System.Collections.Generic; public abstract class Pool<T> : IPool<T> { #region ICountObserverable /// <summary> /// Gets the current count. /// </summary> /// <value>The current count.</value> public int CurCount { get { return mCacheStack.Count; } } #endregion protected IObjectFactory<T> mFactory; protected Stack<T> mCacheStack = new Stack<T>(); /// <summary> /// default is 5 /// </summary> protected int mMaxCount = 5; public virtual T Allocate() { return mCacheStack.Count == 0 ? mFactory.Create() : mCacheStack.Pop(); } public abstract bool Recycle(T obj); } 对象池实现 首先要实现一个对象的创建器,代码如下所示: ...


