引子
在學(xué)習(xí)編程之初我們就知道使用靜態(tài)方法或者是靜態(tài)變量就可以在其他類中使用那個方法那個變量附鸽,但是老師就告訴我們能不用靜態(tài)方法就不用脱拼,因為靜態(tài)的不能繼承巴拉巴拉...就一直很怕使用靜態(tài),直到單例的出現(xiàn)坷备。感覺人生一下子就豁然開朗熄浓。單例與靜態(tài)的區(qū)別 看完了這個總有一種誤會靜態(tài)的感受。哈哈哈省撑。
既然是單例赌蔑,就意味著就只能有一個對象俯在,所以他的構(gòu)造函數(shù)肯定是私有的。
public class MyClass
{
private MyClass()
{
}
}
簡而言之就是這樣了娃惯,這個是我在平時寫的時候經(jīng)常忘記寫的一個跷乐,當(dāng)然不寫也不會報錯,個人覺得寫上還是嚴(yán)謹(jǐn)一些嘛趾浅,哈哈愕提。當(dāng)然繼承于MonoBehriour的類是不建議new的嘛,new的話unity也會給你報警告的皿哨。當(dāng)然如果還是要在實例化對象的話浅侨,就可以不加這個私有構(gòu)造方法。就給大家說說我都用過那幾種寫法嘛往史。下面的例子就不寫這個方法仗颈。
最簡單Awake
public class MyClass : MonoBehaviour
{
public static MyClass instance;
public void Awake()
{
instance = this;
}
}
這樣的寫法是最簡單的,也是最粗暴的椎例。當(dāng)然一般這樣的寫法按照常規(guī)劇本走的話挨决,到后面都不會有好的結(jié)果。用了這個的話在多線線程中是不能好好跟你玩耍的订歪。其實在做一些小demo還是可以這個滴,畢竟簡單嘛盖高。
不繼承于MonoBehavior常規(guī)類
public class MyClass
{
public static MyClass Instance
{
get { return Nest.instance; }
}
private class Nest
{
static Nest()
{
}
internal static readonly MyClass instance = new MyClass();
}
}
這種是靜態(tài)內(nèi)部類喻奥,既是線程安全又沒有消耗太多捏悬。
繼承于MonoBehavior
using UnityEngine;
public class MyClass : MonoBehaviour
{
private static MyClass instance;
public static MyClass Instance
{
get
{
if (!instance)
{
instance = (MyClass) FindObjectOfType(typeof (MyClass));
if (!instance)
{
Debug.LogError("There needs to be one active MyClass script on a GameObject in your scene");
}
}
return instance;
}
}
}
這個寫法是一定要這個腳本掛在游戲物體上的过牙。
平時寫代碼時我們不可能在每一個要使用的單例模式的類中都寫上上面的代碼,太麻煩了刀疙,下面給大家介紹兩種之前遇到的兩種簡便方法扫倡。
單例模板基類
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : class
{
protected static T instance;
public static T Instance
{
get
{
if (null == instance)
{
var type = typeof (T);
if (type.IsAbstract || type.IsInterface)
{
throw (new Exception("Class type must could be instantiated. Don't use abstract or interface"));
}
if (!type.IsSealed)
{
throw (new Exception("Class type must be a sealed. Use sealed"));
}
var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic,
null,
SType.EmptyTypes,
null);
if (null == constructor)
{
throw (new Exception("Constructor must empty"));
}
if (!constructor.IsPrivate)
{
throw (new Exception("Constructor must be a private function"));
}
instance = constructor.Invoke(null) as T;
}
return instance;
}
}
}
這個模板可以繼承于monobehaviour也可以不用油够,繼承于這個基類的類是不能有派生的
變量型單例
using UnityEngine;
public class InstanceManager : MonoBehaviour
{
private static InstanceManager instance;
public static InstanceManager Instance
{
get
{
if (!instance)
{
instance = (InstanceManager) FindObjectOfType(typeof (InstanceManager));
if (!instance)
{
Debug.LogError("There needs to be one active MyClass script on a GameObject in your scene");
}
}
return instance;
}
}
#region add public script
public start Start;
#endregion
}
細(xì)心的你肯定發(fā)現(xiàn)了這樣的寫法與上面繼承于monobehaviour的方式是一樣的石咬,后面加了一個公共的類的變量,這個類就是咱們需要使用的的單例類删性。當(dāng)然這個管理單例腳本也要掛在游戲物體上焕窝,只需要在外面給其賦值。(當(dāng)然也可以動態(tài)賦值巴帮,雖然沒有動態(tài)賦值過榕茧,不過可以試試)
綜合看起來個人覺得第一種模板基類跟適合用來不用放在場景中一些管理器客给,第二種就適合在場景用到的一些單例腳本。