怎么做網(wǎng)站注冊登入頁面搜狗指數(shù)官網(wǎng)
? ? ? 如果某些字段在每個構(gòu)造函數(shù)中都要進行初始化,很多人都喜歡在字段聲明時就進行初始化,對于一個非繼承自MonoBehaviour的腳步,這樣做是沒有問題的,然而繼承自MonoBehaviour后就會造成內(nèi)存的浪費,為什么呢?因為繼承自MonoBehaviour的腳步的構(gòu)造函數(shù)可能會被多次執(zhí)行,這也是為什么Unity的Mono腳步不使用構(gòu)造函數(shù)的原因。而字段在聲明時賦值的結(jié)果其實是會在構(gòu)造函數(shù)中去執(zhí)行,即使沒有聲明構(gòu)造函數(shù),編譯器會在默認(rèn)的無參構(gòu)造函數(shù)中將你的字段初始化放到默認(rèn)的構(gòu)造函數(shù)中去。下面用一個簡單的腳步進行看一下:
public class Test : MonoBehaviour{private List<int> _data = new List<int>();public Test(){Debug.Log("構(gòu)造函數(shù)調(diào)用 -- Test");}void Start(){}}
上面這段代碼就是在聲明字段時就進行了初始化,現(xiàn)在從IL代碼層面上去看一下:
.class public auto ansi beforefieldinit MagicWorld.Testextends [UnityEngine.CoreModule]UnityEngine.MonoBehaviour
{// Fields.field private class [netstandard]System.Collections.Generic.List`1<int32> _data// Methods.method public hidebysig specialname rtspecialname instance void .ctor () cil managed {// Method begins at RVA 0x3639// Header size: 1// Code size: 28 (0x1c).maxstack 8IL_0000: ldarg.0IL_0001: newobj instance void class [netstandard]System.Collections.Generic.List`1<int32>::.ctor() // _data = new List<int>();IL_0006: stfld class [netstandard]System.Collections.Generic.List`1<int32> MagicWorld.Test::_dataIL_000b: ldarg.0IL_000c: call instance void [UnityEngine.CoreModule]UnityEngine.MonoBehaviour::.ctor()IL_0011: ldstr "構(gòu)造函數(shù)調(diào)用 -- Test"IL_0016: call void [UnityEngine.CoreModule]UnityEngine.Debug::Log(object)IL_001b: ret} // end of method Test::.ctor.method private hidebysig instance void Start () cil managed {// Method begins at RVA 0x3656// Header size: 1// Code size: 1 (0x1).maxstack 8IL_0000: ret} // end of method Test::Start} // end of class MagicWorld.Test
如果沒有無參構(gòu)造函數(shù),有很多構(gòu)造函數(shù)的話,上面的代碼會被寫到指向父類的構(gòu)造函數(shù)的那個構(gòu)造函數(shù)中,即:base()。
? ? ? ?如果是靜態(tài)字段在聲明時直接賦值則會在靜態(tài)構(gòu)造函數(shù)中執(zhí)行。?而靜態(tài)構(gòu)造函數(shù)會在程序集加載時由編譯器負(fù)責(zé)調(diào)用。
? ? ? ?因此,建議對于Mono腳本,初始化操作建議放到Awake或Start中去執(zhí)行。在編輯器模式下掛載腳步也是會執(zhí)行腳步的構(gòu)造函數(shù)的。對于靜態(tài)變量建議執(zhí)行懶初始化,即訪問時為null時才執(zhí)行初始化,或者使用C#的Lazy<T>類來完成懶初始化。
? ? ? ? 至少到目前Unity支持的C#9語法來看都是這樣的,以后就不清楚了。?