网站免费在线观看网络营销技巧和营销方法
目录
一、常规单例
二、Unity单例
1. MonoBehaviour单例
2.Simple单例
一、常规单例
常规的单例模式是指在普通类中实现单例模式的方式,而不依赖于任何框架或引擎。这种单例模式在许多编程语言中都非常常见,其主要特点是:
- 单例类有一个私有的静态变量来保存唯一实例。
- 提供一个公有的静态方法(通常是
Instance
方法)来获取唯一实例。 - 将构造函数定义为私有,防止外部创建新的实例。
public class Singleton
{// 用来保存唯一的实例private static Singleton instance = null;// 确保线程安全的锁对象private static readonly object lockObj = new object();// 私有构造函数,防止实例化private Singleton(){}// 获取唯一实例的公有静态方法public static Singleton Instance{get{// 双重检查锁定(double-checked locking)if (instance == null){lock (lockObj){if (instance == null){instance = new Singleton();}}}return instance;}}// 单例类中的方法示例public void DoSomething(){Console.WriteLine("Singleton instance is doing something.");}
}
二、Unity单例
1. MonoBehaviour单例
适合在需要动态创建单例对象的场合,并能处理场景切换等复杂情况。
优点:
- 懒加载:
Instance
属性只有在第一次访问时才会创建实例,这有助于减少不必要的开销。 - DontDestroyOnLoad:使用
DontDestroyOnLoad
保证实例在在场景切换时不被销毁。 - 防止重复创建单例:在销毁时设置
mIsDestroying
标记,防止对已销毁单例进行重复创建。
缺点:
- GameObject创建管理:它通过
new GameObject().AddComponent<MonoBehaviourSingleton>()
的方式创建实例,这在某些情况下过于灵活,可能导致难以管理和调试。 - 静态变量的潜在问题:如果游戏中对于对象销毁和创建的逻辑非常复杂,可能会因为静态变量状态互相干扰造成潜在的问题。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MonoBehaviourSingleton : MonoBehaviour
{static bool mIsDestroying; //判断销毁的静态变量static MonoBehaviourSingleton mInstance;public static MonoBehaviourSingleton Instance{get{if (mInstance == null){if (mIsDestroying){Debug.LogWarning("[MonoBehaviourSingleton] Instance '" + typeof(MonoBehaviourSingleton) +"' already destroyed. Returning null.");return null; //如果已销毁则跳出,防止嵌套调用}mInstance = new GameObject("[MonoBehaviourSingleton]").AddComponent<MonoBehaviourSingleton>();DontDestroyOnLoad(mInstance.gameObject); //创建实例并设置为DontDestroyOnLoad}return mInstance;}}public void Test(){Debug.Log("Test");}void OnDestroy(){mIsDestroying = true; //销毁时将标记变量设置为true,防止对已销毁单例进行重复创建}
}
2.Simple单例
更直观简单,但需要确保对象在场景中存在且被正确管理,不适合频繁切换场景的情况。
优点:
- 更容易管理:不用手动创建GameObject,更多依赖于Unity编辑器来管理单例对象的创建。
- 避免重复实例:通过比较
instance
和this
,可以确保在同一场景中只存在一个实例。
缺点:
- 缺乏灵活性:不能像前一种方法那样灵活创建实例,必须确保在场景中包含该组件对应的对象。
- 潜在的实例丢失问题:如果
SimpleSingleton
对象不在初始场景中,可能会引发问题,如果有依赖该单例的其他代码在实例初始化之前执行,会出现空引用错误。
using UnityEngine;public class SimpleSingleton : MonoBehaviour
{private static SimpleSingleton instance;public static SimpleSingleton Instance{get{if (instance == null){Debug.LogError("Singleton instance has not been set. Make sure the singleton is properly instantiated.");}return instance;}}protected virtual void Awake(){if (instance == null){instance = this;DontDestroyOnLoad(gameObject);}else if (instance != this){Destroy(gameObject);}}public void Test(){Debug.Log("Test");}
}