引用计数是一个很好用的技术概念,不要被这个名字吓到了。首先来说讲引用计数是干吗的。git
有一间黑色的屋子,里边有一盏灯。当第一我的进屋的时候灯会打开,以后的人进来则不用再次打开了,由于已经开过了。当屋子里的全部人离开的时候,灯则会关闭。github
咱们先定义灯的对象模型:c#
class Light { public void Open() { Log.I("灯打开了"); } public void Close() { Log.I("灯关闭了"); } }
很简单就是两个方法而已。微信
再定义屋子的类,屋子应该持有一个Light的对象,而且要记录人们的进出。当有人进入,进入后当前房间只有一我的的时候,要把灯打开。当最后一我的离开的时候灯要关闭。框架
代码以下:ide
class Room { private Light mLight = new Light(); private int mPeopleCount = 0; public void EnterPeople() { if (mPeopleCount == 0) { mLight.Open(); } ++mPeopleCount; Log.I("一我的走进房间,房间里当前有{0}我的",mPeopleCount); } public void LeavePeople() { --mPeopleCount; if (mPeopleCount == 0) { mLight.Close(); } Log.I("一我的走出房间,房间里当前有{0}我的", mPeopleCount); } }
很简单,咱们来看下测试代码。测试
var room = new Room(); room.EnterPeople(); room.EnterPeople(); room.EnterPeople(); room.LeavePeople(); room.LeavePeople(); room.LeavePeople(); room.EnterPeople();
看下输出的结果:3d
灯打开了 一我的走进房间,房间里当前有1我的 一我的走进房间,房间里当前有2我的 一我的走进房间,房间里当前有3我的 一我的走出房间,房间里当前有2我的 一我的走出房间,房间里当前有1我的 一我的走出房间,房间里当前有0我的 灯关闭了 灯打开了 一我的走进房间,房间里当前有1我的
OK.以上就是引用计数这项计数的使用场景的全部代码。
测试的代码比较整齐,很容易算出来当前有多少我的在屋子里,因此看不出来引用计数的做用。可是在平常开发中,咱们可能会把EnterPeople和LeavePeople散落在工程的各个位置。这样就很难统计,这时候引用计数的做用就很明显了,它能够自动帮助你判断何时进行开灯关灯操做,而你不用写开关灯的一行代码。code
这个例子比较接近生活,假如笔者再换个例子,咱们把Light对象换成资源对象,其开灯对应加载资源,关灯对应卸载资源。而屋子则是对应资源管理器,EnterPeople对应申请资源对象,LeavePeople对应归还资源对象。这样你只管在各个界面中申请各个资源,只要在界面关闭的时候归还各个资源对象就能够不用关心资源的加载和卸载了,能够减轻大脑的负荷。视频
计数器的接口很简单,代码以下:
public interface IRefCounter { int RefCount { get; } void Retain(object refOwner = null); void Release(object refOwner = null); }
Retain是增长引用计数(RefCount+1),Release减去一个引用计数(RefCount—)。
在接下来的具体实现中,当RefCount降为0时咱们须要捕获一个事件,这个事件叫OnZeroRef。
代码以下:
public class SimpleRC : IRefCounter { public SimpleRC() { RefCount = 0; } public int RefCount { get; private set; } public void Retain(object refOwner = null) { ++RefCount; } public void Release(object refOwner = null) { --RefCount; if (RefCount == 0) { OnZeroRef(); } } protected virtual void OnZeroRef() { } }
以上就是简易引用计数器的全部实现了。
接下来咱们用这个引用计数器,重构灯的使用场景的代码。
class Light { public void Open() { Log.I("灯打开了"); } public void Close() { Log.I("灯关闭了"); } } class Room : SimpleRC { private Light mLight = new Light(); public void EnterPeople() { if (RefCount == 0) { mLight.Open(); } Retain(); Log.I("一我的走进房间,房间里当前有{0}我的",RefCount); } public void LeavePeople() { // 当前还没走出,因此输出的时候先减1 Log.I("一我的走出房间,房间里当前有{0}我的", RefCount - 1); // 这里才真正的走出了 Release(); } protected override void OnZeroRef() { mLight.Close(); } }
测试代码和以前的同样,咱们看下测试结果:
灯打开了 一我的走进房间,房间里当前有1我的 一我的走进房间,房间里当前有2我的 一我的走进房间,房间里当前有3我的 一我的走出房间,房间里当前有2我的 一我的走出房间,房间里当前有1我的 一我的走出房间,房间里当前有0我的 灯关闭了 灯打开了 一我的走进房间,房间里当前有1我的
好了,今天就到这里
个人框架地址:https://github.com/liangxiegame/QFramework
教程源码:https://github.com/liangxiegame/QFramework/tree/master/Assets/HowToWriteUnityGameFramework/
QFramework&游戏框架搭建QQ交流群: 623597263
转载请注明地址:凉鞋的笔记http://liangxiegame.com/
微信公众号:liangxiegame
若是以为本篇教程或者 QFramework 对您有帮助,不妨经过如下方式赞助笔者一下,鼓励笔者继续写出更多高质量的教程,也让更多的力量加入 QFramework 。
笔者在这里保证 QFramework、入门教程、文档和此框架搭建系列的专栏永远免费开源。以上捐助产品的内容对于使用 QFramework 的使用来说都不是必须的,因此你们不用担忧,各位使用 QFramework 或者 阅读此专栏 已是对笔者团队最大的支持了。