以懒汉式为例:
public class GameCtrl
{
#region 正常单例
private GameCtrl()
{
Debug.Log("GameCtrl");
}
private static GameCtrl m_Instance = null;
public static GameCtrl Instance
{
get
{
Debug.Log("get");
if (m_Instance == null)
{
m_Instance = new GameCtrl();
}
return m_Instance;
}
}
#endregion
}
点击事件:
private void OnBtnClick()
{
Debug.Log("OnBtnClick");
GameCtrl.Instance.PopHintMsg();
}
- 运行unity打印结果:空
- 第一次点击按钮打印结果:
- 第二次点击按钮打印结果:
总结:构造函数在第一次get之后调用一次,所以第一次用的时候new,后面实例已经存在直接返回
public class GameCtrl : MonoBehaviour
{
#region 继承MonoBehaviour的单例
private GameCtrl()
{
m_Instance = this;
Debug.Log("GameCtrl");
}
private static GameCtrl m_Instance = null;
public static GameCtrl Instance
{
get
{
Debug.Log("get");
return m_Instance;
}
}
#endregion
// -------------分割线,以下为辅助阅读代码,与单例没关系-----------------
private void Awake()
{
Debug.Log("Awake");
}
public void PopHintMsg()
{
}
}
- 运行unity打印结果:
- 第一次点击按钮打印结果:
- 第二次点击按钮打印结果:同第一次
注意:与普通单例的构造函数有所区别,构造函数在运行游戏时立刻调用,每次用的时候实例都已经存在了
疑问:
- 正常单例情况下断点,发现每次get时Instance就已经实例化出来过了,而断点又进不去构造函数是为何?(采用打印的方法是正常的、符合预期的)
- 为什么运行unity就会执行构造方法?而且还执行了2次,并且停止游戏时也会运行一次构造方法(图上没贴出来),不知为何
- 为什么采用和正常单例相似的方式,在属性中判断是否为空,空了new出来不行?(new之后仍然为空)而要在构造函数中(Awake或者Start中)=this
猜测: MonoBehaviour将new方法复写了,m_Instance = this
最好写在Awake中因为最先且只调用一次