1. 最简单的单例
代码简单适合单例很少的项目,非线程安全
public class instance_normal
{
// 单例对象
private static instance_normal instance;
// 获取单例
public static instance_normal GetInstance
{
get
{
if (instance == null)
{
instance = Activator.CreateInstance<instance_normal>();
}
return instance;
}
}
public void Init()
{
Debug.Log("instance_normal.Init");
}
/// <summary>
/// 首次调用的时候需要实例化
/// </summary>
// instance_normal.GetInstance.Init();
}
2. 简单的泛型单例
/// <summary>
/// 代码简单,继承Singleton<T>类就可以继承实现单例类。
/// 因为泛型约束中使用new(),因此子类无法私有化构造函数,子类依然可以通过new来实例化对象。
/// 适合单例使用较多的项目。
/// </summary>
/// <typeparam name="T"></typeparam>
public class Singleton<T> where T : class, new()
{
private static T instance = default(T);
public static T GetInstance()
{
if (instance == null)
{
instance = new T();
}
return instance;
}
}
泛型单例的使用
public class GameManager : Singleton<GameManager>
{
/// <summary>
/// 初始化
/// </summary>
public void InitGame()
{
Debug.Log("GameManager.Init");
}
}
/// <summary>
/// 调用方式
/// </summary>
/// GameManager.GetInstance().InitGame();
3. 静态内部类
静态成员的初始化是在类进行装载的时候进行的,在没有调用过GetSingleton()方法之前InitSingleton_S类没有进行任何调用,所以Singleton_S的单例也没有初始化。
public class Singleton_S
{
Singleton_S() {
}
// 使用静态内部类完成初始化
private static class InitSingleton_S
{
public static Singleton_S Instance = new Singleton_S();
}
// 提供给外界进行调用实例的方法
public static Singleton_S GetSingleton_S()
{
return InitSingleton_S.Instance;
}
}
4. 继承自MonoBehaviour的简单单例
需要挂载在场景的GameObject中
public class Singleton_M : MonoBehaviour
{
// 创建静态实例
public static Singleton_M instance;
// 防止外部进行额外的实例化将构造函数设为private
private Singleton_M()
{
}
private void Awake()
{
instance = this;
}
}
5. 场景中常驻的单例
public class GameMgr : MonoBehaviour
{
private static GameMgr instance;
public static GameMgr GetInstance
{
get
{
if (instance == null)
{
// 新建单例挂在新建Obj上
GameObject obj = new GameObject("GameMgrObj");
instance = obj.AddComponent<GameMgr>();
// 将挂载单例Obj设为不销毁的对象
DontDestroyOnLoad(obj);
}
return instance;
}
}
public void Init()
{
Debug.Log("GameMgr.Init");
}
}
6. 单例的销毁
单例如果没有及时销毁,里面对其它类的引用就会一直持有,GC的时候无法回收这部分内存占用,必定造成内存泄漏。所以需要销毁的单例类一定要加入销毁方法。
public static bool DestoryInstance()
{
if (instance == null)
{
return false;
}
instance = null;
return true;
}
7. 使用扩展方法代替直接使用单例
例如:
频繁使用的缓存池回收方法,回收方法需要进行其他操作直接在扩展方法里修改就好,不比去一个个修改或者直接修改缓存池的代码。
public static void RecycleObj( this GameObject obj, int count = 1 )
{
// 缓存池回收
PoolManager.instance.RecycleObj( obj, count );
}
Unity的输出方法
public static class Console
{
public static void Log(object message, UnityEngine.Object context = null)
{
Debug.Log("<b>Log: </b>" + message, context);
}
public static void LogFormat(string format, params object[] args)
{
Debug.LogFormat("<b>Log: </b>" + format, args);
}
}