Unity中的单例总结
单例模式是程序员在编程时接触到的最基础设计模式之一,简单一句话概括就是对象的唯一实例。
在unity中的单例模板有以下几种
非Monobehavior下的单例
- 使用反射的单例模式
using System;
using System.Reflection;
public abstract class Singleton<T> where T : Singleton<T>
{
protected Singleton()
{
Init();
}
protected static T instance = null;
public static T Instance
{
get
{
if (instance == null)
{
var constructors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
var constructor = Array.Find(constructors, c => c.GetParameters().Length == 0);
if (constructor == null)
throw new Exception("non-public constructor not find");
instance = constructor.Invoke(null) as T;
}
return instance;
}
}
protected virtual void Init() { }
}
使用反射获取非公有 构造无参函数,并进行初始化
- 使用关键字 new() 限定,必须含有无参构造函数的单例
using System;
using System.Reflection;
public abstract class Singleton<T> where T : Singleton<T>, new()
{
protected Singleton()
{
Init();
}
protected static T instance = null;
public static T Instance
{
get
{
if (instance == null)
{
instance = new T();
}
return instance;
}
}
protected virtual void Init() { }
}
使用new()关键字限定无参构造函数,子类继承时必须实现公有构造函数
- 使用双重锁的单例模式
using System;
using System.Reflection;
public abstract class Singleton<T> where T : Singleton<T>
{
protected Singleton()
{
Init();
}
protected static T instance = null;
private static readonly object objectLock = new object();
public static T Instance
{
get
{
if (instance == null)
{
lock (objectLock)
if (instance == null)
{
...初始化过程...
}
}
return instance;
}
}
protected virtual void Init() { }
}
使用 双重锁确保单例在多线程初始化时的线程安全性
MonoBehavior的单例实现
using UnityEngine;
public class BehaviorSingleton<T> : MonoBehaviour where T : BehaviorSingleton<T>
{
private static T instance = null;
public static T Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType<T>();
if (instance == null)
{
var gameObject = new GameObject(typeof(T).Name);
DontDestroyOnLoad(gameObject);
instance = gameObject.AddComponent<T>();
}
}
return instance;
}
}
private void Awake()
{
//确保唯一性
if (instance == null)
{
DontDestroyOnLoad(gameObject);
gameObject.name = typeof(T).Name;
instance = GetComponent<T>();
InstanceAwake();
}
else
Destroy(gameObject);
}
private void OnApplicationQuit()
{
instance.InstanceDestroy();
instance = null;
}
protected virtual void InstanceAwake() { }
protected virtual void InstanceDestroy() { }
}
网友评论