1. 程式人生 > >Mono生命周期函數調用機制分析

Mono生命周期函數調用機制分析

不可 依然 .get ret 分析 一個 bubuko IT unity

1.生命周期函數的調用機制是反射,而並非繼承。

我們打開Mono後發現其的確也沒有生命周期函數的實現,向上翻父類中也沒有,好,可以確定其就不是繼承了。

下面驗證下是否是反射,拿void start()函數來說,其原本是private,但如果你硬要改成public,其執行起來也什麽影響(但你肯定不想外界去手動調用你的Start吧),甚至於你把它設置成private IEnumerator Start()都可以,因為是發射調用嘛,名字對了就可以。如下圖

技術分享圖片 技術分享圖片

(針對Start使用IEnumerator是肯定可以的,但其他生命周期函數好像不可以這麽用,具體為什麽不可以查過沒查到很詳細的回答,我想應該是Unity內部實現機制上就這麽規定只有start返回類型可以是IEnumerator吧,朋友們有了解這方面的歡迎留言指導)

2.Unity在當前Mono子類中找不到對應函數時,會主動再去父類中找

比如我們設定:

public class People : MonoBehaviour
{
    private void Start ()
    {
        Debug.Log("執行People的Start函數");
    }
}

public class Teacher : People
{
    void Start ()
    {
        Debug.Log("執行了Teacher的Start函數");
    }
}

a.這種是最基本的情況,大家肯定都知道,這是執行Teacher的Start函數,而people的Start函數不執行;

b. 但如果我把Teacher的Start函數去掉後,如下

public class Teacher : People
{
}

此時再運行,就會發現其會執行父類People的Start函數。這裏註意,Teacher的Start函數必須直接去掉,不能如下這樣

private void Start ()
{
    //Debug.Log("執行People的Start函數");
}

因為這樣也算是有Start函數,Unity通過反射會在Teacher中查找到,故不會再去People中查找。其實。其實這一點很重要,很多子類要掩蓋父類的生命周期函數的時候,經常會手寫一個空的去覆蓋,你要是覺得這個空函數沒用直接刪了,那就錯了。

3.那當調用父類Start函數時,其Start內部調用成員函數的機制是什麽樣的呢,且看下面:

public class People : MonoBehaviour
{
    private  void Start ()
    {
        Debug.Log("執行People的Start函數 +"+ this.GetType().ToString());
        Debug.Log("執行People的Start函數 +" + this.Sign());
        Debug.Log("執行People的Start函數 +" + this.Mark());
    }
    public virtual string Sign()
    {
        return "This is belong to People";
    }
    public virtual string Mark()
    {
        return "People Mark";
    }
}

public class Teacher : People
{
    //void Start ()
    //   {
    //       Debug.Log("執行了Teacher的Start函數");
    //}
    public override string Sign()
    {
        return "This is belong to Teacher";
    }
    public new string Mark()
    {
        return "Teacher Mark";
    }
}

最後執行結果:

技術分享圖片

所以,當執行父類的Start函數時,其機制采用的就是多態,聲明的是父類,子類的實現(父類的殼,子類的填充),所以我們在項目中構建父類框架時,就可以隨心所欲的寫,如果子類中要改寫哪個函數,直接overide重寫就可以了,這是很方便的。

同時,還有一點,你會發現上述代碼中,people的Start函數不論聲明是public還是private,對結果都不影響,也就是說Unity對於這個地方的原則就是:讓父類中私有生命周期函數的也可以被子類訪問到(用反射模擬實現),其他的依然符合多態和繼承的概念。

Mono生命周期函數調用機制分析