继承MonoBehaviour的单例

以懒汉式为例:

  • 正常单例

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();
    }
  1. 运行unity打印结果:空
  2. 第一次点击按钮打印结果:
    继承MonoBehaviour的单例_第1张图片
  3. 第二次点击按钮打印结果:
    继承MonoBehaviour的单例_第2张图片

总结:构造函数在第一次get之后调用一次,所以第一次用的时候new,后面实例已经存在直接返回

  • 继承MonoBehaviour的单例

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()
    {
    }
}
  1. 运行unity打印结果:
    继承MonoBehaviour的单例_第3张图片
  2. 第一次点击按钮打印结果:
    继承MonoBehaviour的单例_第4张图片
  3. 第二次点击按钮打印结果:同第一次
    继承MonoBehaviour的单例_第5张图片
    注意:与普通单例的构造函数有所区别,构造函数在运行游戏时立刻调用,每次用的时候实例都已经存在了

疑问:

  1. 正常单例情况下断点,发现每次get时Instance就已经实例化出来过了,而断点又进不去构造函数是为何?(采用打印的方法是正常的、符合预期的)
  2. 为什么运行unity就会执行构造方法?而且还执行了2次,并且停止游戏时也会运行一次构造方法(图上没贴出来),不知为何
  3. 为什么采用和正常单例相似的方式,在属性中判断是否为空,空了new出来不行?(new之后仍然为空)而要在构造函数中(Awake或者Start中)=this
    猜测: MonoBehaviour将new方法复写了,m_Instance = this最好写在Awake中因为最先且只调用一次

你可能感兴趣的:(Unity)