Unity 遊戲框架搭建 (二十二) 簡易引用計數器

引用計數是一個很好用的技術概念,不要被這個名字嚇到了。首先來說講引用計數是幹嗎的。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 或者 閱讀此專欄 已是對筆者團隊最大的支持了。

相關文章
相關標籤/搜索