长久以来,对于基于MonoBehaviour的单例总是心有梗结,总觉得用得很忐忑,今天,终于有时间思考和总结了下,理清了想通了。代码和注释如下:
其中GameLogic是我们自己的控制游戏生命周期的管理类,当游戏进行中,GameLogic.AddComponent总是成功的添加组件到一个标记为DontDestroyOnLoad的对象上,这样保证单例的生命期。
当游戏结束后,开始数据清理时,如果调用 GameLogic.AddComponent就会返回null,这样保证在游戏结束的清理工作中已销毁置空的单例不会因为误引用而【死而复生】
class UICanvasManager : MonoBehaviour { /*** 基于MonoBehaviour的单例规则,保证单例的唯一性和安全性 * 1,不要手动在编辑器中挂给对象,防止挂重 * 2,使用如下方式通过GameLogic生成单例,生命周期易控制 * 3,不要在AWake或其它任何地方给_instance赋值,保证单例唯一,不变。考虑以下【危险案例】 */ /*** 【危险案例】 * 先通过UICanvasManager.Instance获取了一个指向对象A的单例,进行一些操作后,A中有了一些数据, * 后面不小心通过AddComponent添加了一个UICanvasManager组件,此时单例指向了对象B * 这时候有一些游戏数据在对象A中,有一些数据在对象B中,后果是B中有些你以为已经初始化了的数据却为空 */ protected static UICanvasManager _instance; public static UICanvasManager Instance { get { if(_instance == null) { _instance = GameLogic.AddComponent<UICanvasManager>(); } return _instance; }//get }//Instance }