[Unity3D教程]Unity中如何编写对象重用池机制
对象重用池的概念其实非常简单:创建使用后的对象不会直接销毁,而是存储在一个池子中,当需要时在可在池子中拿出再供使用。
对象池的最重要的特性,也就是对象池设计模式的本质是允许我们获取一个“新的”对象而不管它真的是一个新的对象还是循环使用的对象。
对象重用池是典型“空间换时间”案例。通过减少CPU调用系统调用时的资源消耗,转为对内存的长期占用,进而达到提升“处理速度”的效果。也就是说:对象重用池是对CUP的优化,而不是对内存的优化策略(反而是增加负担了呢)。
对象重用池机制在各个语言中都普遍存在,有些语言甚至将重用池机制封装到了框架底层,比如iOS中的TableViewCell的重用机制。在Unity中的用户自定义对象并没有现成类来提供重用管理,这个功能需要我们自己编写。
对象重用池的方案有非常多的成熟框架供我们使用,甚至三言两语就能勾勒出一幅重用池:
#使用堆栈模拟一个简单的对象重用池#
使用方法:
当然, 上述代码只能出现在演示Demo中, 它实在是太简单了。事实上,如果你搜索下用Unity实现的对象池类库,你会发现其中很多是相当复杂的。我们先来分析下一个合格的对象池应该具备哪些优秀品质:
• 对象进入对象池之时,应该提供接口事件,通知用户该事件。
• 从池子中拿出的对象时,应该提供接口事件,用户可以在方法内对该对象进行操作,比如重置、刷新数据。
• 能够管理多种对象。
• 能够提供清理池子的接口,甚至提供定期自动清理策略。
• 某些类型的资源是很珍贵的(如数据库连接),池需要显示上限并提供一个针对分配对象失败的安全措施;
• 对于需要长期持有的资源,如网络连接、数据库连接等资源,需要提供分配失败的安全措施。
• 线程安全的。
在此提供一种实现思路:
• 面向用户的ObjectPoolCtrl(对象池管理类)类:
该类直接与用户交互且负责管理多个对象池子.
• 能够进入池子的对象需要遵循的协议IReuse
• 能够进入池子的对象基类ReuseObject
• 池子类SubPool,真正妇科管理对象
关系示意图:
接口代码:
public interface IReuse {
void Spawn();
void UnSpawn();
}
基类代码:
using UnityEngine;
public abstract class ReuseObject : MonoBehaviour, IReuse {
// 所有类的基类, 想要进入池子的对象不要在继承MonoBehaviour了
//