游戏蛮牛学习群(纯技术交流,不闲聊):159852603
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2355

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 2961|回复: 51

[凉鞋同学] Unity 游戏框架搭建 (二十二) 简易引用计数器

[复制链接]  [移动端链接]
排名
2217
昨日变化
2

35

主题

472

帖子

2266

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
64
蛮牛币
2427
威望
0
注册时间
2016-5-17
在线时间
747 小时
最后登录
2018-11-19

专栏作家

QQ
发表于 2018-1-27 19:53:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 liangxiegame 于 2018-8-11 19:11 编辑

引用计数是一个很好用的技术概念,不要被这个名字吓到了。首先来讲讲引用计数是干嘛的。


引用计数使用场景
有一间黑色的屋子,里边有一盏灯。当第一个人进屋的时候灯会打开,之后的人进来则不用再次打开了,因为已经开过了。当屋子里的所有人离开的时候,灯则会关闭。
我们先定义灯的对象模型:
[C#] 纯文本查看 复制代码
    class Light
    {
        public void Open()
        {
            Log.I("灯打开了");
        }

        public void Close()
        {
            Log.I("灯关闭了");
        }
    }

很简单就是两个方法而已。
再定义屋子的类,屋子应该持有一个Light的对象,并且要记录人们的进出。当有人进入,进入后当前房间只有一个人的时候,要把灯打开。当最后一个人离开的时候灯要关闭。
代码如下:
[C#] 纯文本查看 复制代码
    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);
        }
    }

很简单,我们来看下测试代码。
[C#] 纯文本查看 复制代码
            var room = new Room();
            room.EnterPeople();
            room.EnterPeople();
            room.EnterPeople();

            room.LeavePeople();
            room.LeavePeople();
            room.LeavePeople();

            room.EnterPeople();

看下输出的结果:
[C#] 纯文本查看 复制代码
灯打开了
一个人走进房间,房间里当前有1个人
一个人走进房间,房间里当前有2个人
一个人走进房间,房间里当前有3个人
一个人走出房间,房间里当前有2个人
一个人走出房间,房间里当前有1个人
一个人走出房间,房间里当前有0个人
灯关闭了
灯打开了
一个人走进房间,房间里当前有1个人

OK.以上就是引用计数这项技术的使用场景的所有代码。 测试的代码比较整齐,很容易算出来当前有多少个人在屋子里,所以看不出来引用计数的作用。但是在日常开发中,我们可能会把EnterPeople和LeavePeople散落在工程的各个位置。这样就很难统计,这时候引用计数的作用就很明显了,它可以自动帮助你判断什么时候进行开灯关灯操作,而你不用写开关灯的一行代码。
这个例子比较接近生活,假如笔者再换个例子,我们把Light对象换成资源对象,其开灯对应加载资源,关灯对应卸载资源。而屋子则是对应资源管理器,EnterPeople对应申请资源对象,LeavePeople对应归还资源对象。这样你只管在各个界面中申请各个资源,只要在界面关闭的时候归还各个资源对象就可以不用关心资源的加载和卸载了,可以减轻大脑的负荷。
简易计数器实现:
计数器的接口很简单,代码如下:
[C#] 纯文本查看 复制代码
    public interface IRefCounter
    {
        int RefCount { get; }

        void Retain(object refOwner = null);
        void Release(object refOwner = null);
    }

Retain是增加引用计数(RefCount+1),Release减去一个引用计数(RefCount—)。 在接下来的具体实现中,当RefCount降为0时我们需要捕获一个事件,这个事件叫OnZeroRef。 代码如下:
[C#] 纯文本查看 复制代码
    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()
        {
        }
    }

以上就是简易引用计数器的所有实现了。
接下来我们用这个引用计数器,重构灯的使用场景的代码。
[C#] 纯文本查看 复制代码
    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();
        }
    }

测试代码和之前的一样,我们看下测试结果:
[C#] 纯文本查看 复制代码
灯打开了
一个人走进房间,房间里当前有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 一个 Star
    • 地址: https://github.com/liangxiegame/QFramework
  • 给 Asset Store 上的 QFramework 并给个五星(需要先下载)
    • 地址: http://u3d.as/SJ9
  • 购买 gitchat 话题:《命名的力量:变量》
    • 价格: 12 元
    • 地址: https://gitbook.cn/gitchat/activity/5b65904096290075f5829388
  • 购买同名的蛮牛视频课程录播课程:
    • 价格 49.2 元
    • 地址: http://edu.manew.com/course/431
  • 购买同名电子书:https://www.kancloud.cn/liangxiegame/unity_framework_design
    • 价格 49.2 元,内容会在 2018 年 10 月份完结






回复

使用道具 举报

3偶尔光临
166/300
排名
13507
昨日变化
4

0

主题

61

帖子

166

积分

Rank: 3Rank: 3Rank: 3

UID
137409
好友
0
蛮牛币
3
威望
0
注册时间
2016-2-24
在线时间
45 小时
最后登录
2018-4-9
发表于 2018-1-28 19:16:18 | 显示全部楼层
看下。。。支持下。。。。

回复

使用道具 举报

5熟悉之中
687/1000
排名
2944
昨日变化
2

1

主题

23

帖子

687

积分

Rank: 5Rank: 5

UID
257829
好友
0
蛮牛币
1648
威望
0
注册时间
2017-12-4
在线时间
189 小时
最后登录
2018-10-31
发表于 2018-1-29 09:13:20 | 显示全部楼层
谢谢分享

回复

使用道具 举报

5熟悉之中
843/1000
排名
5596
昨日变化
4

0

主题

436

帖子

843

积分

Rank: 5Rank: 5

UID
146677
好友
9
蛮牛币
2735
威望
0
注册时间
2016-4-25
在线时间
168 小时
最后登录
2018-10-24
QQ
发表于 2018-1-29 09:17:41 | 显示全部楼层
支持楼主,加油

回复

使用道具 举报

5熟悉之中
565/1000
排名
4089
昨日变化
1

0

主题

75

帖子

565

积分

Rank: 5Rank: 5

UID
52730
好友
1
蛮牛币
942
威望
0
注册时间
2014-11-3
在线时间
150 小时
最后登录
2018-10-30
发表于 2018-1-29 09:27:23 | 显示全部楼层
好文章,谢谢分享。

回复

使用道具 举报

6蛮牛粉丝
1138/1500
排名
3669
昨日变化
3

0

主题

527

帖子

1138

积分

Rank: 6Rank: 6Rank: 6

UID
156480
好友
0
蛮牛币
1849
威望
0
注册时间
2016-7-12
在线时间
225 小时
最后登录
2018-3-16
发表于 2018-1-29 09:29:19 | 显示全部楼层
6666666666

回复

使用道具 举报

4四处流浪
499/500
排名
13043
昨日变化
3

3

主题

152

帖子

499

积分

Rank: 4

UID
216830
好友
2
蛮牛币
373
威望
0
注册时间
2017-4-9
在线时间
280 小时
最后登录
2018-11-20
发表于 2018-1-29 09:40:42 | 显示全部楼层
谢谢分享

回复

使用道具 举报

6蛮牛粉丝
1016/1500
排名
3462
昨日变化
4

1

主题

371

帖子

1016

积分

Rank: 6Rank: 6Rank: 6

UID
122160
好友
1
蛮牛币
1669
威望
0
注册时间
2015-9-10
在线时间
236 小时
最后登录
2018-8-1
发表于 2018-1-29 10:07:39 | 显示全部楼层
感谢分享

回复

使用道具 举报

5熟悉之中
591/1000
排名
6847
昨日变化
2

0

主题

285

帖子

591

积分

Rank: 5Rank: 5

UID
250350
好友
2
蛮牛币
588
威望
0
注册时间
2017-10-23
在线时间
124 小时
最后登录
2018-11-10
发表于 2018-1-29 10:15:14 | 显示全部楼层

谢谢分享
[发帖际遇]: liuwenjiandm 在论坛发帖时没有注意,被小偷偷去了 1 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

6蛮牛粉丝
1206/1500
排名
2319
昨日变化
11

10

主题

184

帖子

1206

积分

Rank: 6Rank: 6Rank: 6

UID
252607
好友
5
蛮牛币
3134
威望
0
注册时间
2017-11-5
在线时间
422 小时
最后登录
2018-11-20
发表于 2018-1-29 11:58:31 | 显示全部楼层
谢谢分享

回复

使用道具 举报

7日久生情
1612/5000
排名
1436
昨日变化
1

1

主题

226

帖子

1612

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
2272
好友
3
蛮牛币
1612
威望
0
注册时间
2013-8-20
在线时间
545 小时
最后登录
2018-11-16

VIP

发表于 2018-1-29 13:56:06 | 显示全部楼层

谢谢分享
[发帖际遇]: fengjian1230 乐于助人,奖励 3 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

7日久生情
4177/5000
排名
163
昨日变化
1

18

主题

314

帖子

4177

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
67323
好友
1
蛮牛币
3338
威望
0
注册时间
2015-1-10
在线时间
1646 小时
最后登录
2018-10-26
发表于 2018-1-29 15:23:30 | 显示全部楼层
好文章 谢谢分享。

回复

使用道具 举报

排名
2217
昨日变化
2

35

主题

472

帖子

2266

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
64
蛮牛币
2427
威望
0
注册时间
2016-5-17
在线时间
747 小时
最后登录
2018-11-19

专栏作家

QQ
 楼主| 发表于 2018-1-29 16:48:47 | 显示全部楼层
AlexGau 发表于 2018-1-28 19:16
看下。。。支持下。。。。

谢谢支持

回复 支持 反对

使用道具 举报

排名
2217
昨日变化
2

35

主题

472

帖子

2266

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
64
蛮牛币
2427
威望
0
注册时间
2016-5-17
在线时间
747 小时
最后登录
2018-11-19

专栏作家

QQ
 楼主| 发表于 2018-1-29 16:49:04 | 显示全部楼层

谢谢支持

回复 支持 反对

使用道具 举报

3偶尔光临
264/300
排名
9052
昨日变化
4

1

主题

52

帖子

264

积分

Rank: 3Rank: 3Rank: 3

UID
194221
好友
0
蛮牛币
505
威望
0
注册时间
2016-12-19
在线时间
90 小时
最后登录
2018-11-19
发表于 2018-1-29 21:06:07 | 显示全部楼层

好文章 谢谢分享。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关闭

站长推荐 上一条 /1 下一条

快速回复 返回顶部 返回列表