保证一个类只有一个实例,并提供一个访问他的函数。
第一种最简单,但没有考虑线程安全,在多线程时会出问题。
public class Singleton { private static Singleton _instance = null; private Singleton(){} public static Singleton CreateInstance() { if(_instance == null) { _instance = new Singleton(); } return _instance; } }
第二种考虑了多线程的情况,增加了锁。
public class Singleton { private volatile static Singleton _instance = null; private static readonly object lockHelper = new object(); private Singleton(){} public static Singleton CreateInstance() { if(_instance == null) { lock(lockHelper) { if(_instance == null) _instance = new Singleton(); } } return _instance; } }
将单例应用到u3d开发当中
public abstract class U3DSingleton<T> : MonoBehaviour where T : U3DSingleton<T> { private static T m_instance = null; private static readonly object lockHelper = new object(); public static T instance{ get{ if( m_instance == null ) { lock(lockHelper) { m_instance = FindObjectOfType(typeof(T)) as T; if( m_instance == null ){ m_instance = new GameObject("Singleton of " + typeof(T).ToString(), typeof(T)).GetComponent<T>(); } } } return m_instance; } } public void InitSingle(){ if( m_instance == null ){ m_instance = this as T; } } }
此类在使用的时候只需要让使用者继承它即可,但是在unity3d编程中若是初始化就是inactive的物体,
FindObjectOfType函数会返回为空,这时候就不能返回我们脚本所挂物体的对象了,那么就需要我们在子类的Awake函数里面自己调用
InitSingle函数。
继承的使用方式不利于扩展,我们可以在子类中使用组合的方式,如下
public class GameTool : MonoBehaviour { public GameTool GetInstance() { return U3DSingleton<GameTool>.instance; } }