一、前言
单例模式:目的是为了让一个类在程序运行期间有且只有一个实例,方便全局访问。
用途:Unity中用作数据类、工具类、实现类,方便脚本调用。
实现流程
1.私有的构造函数,使用static静态字段
static属性在此类中是唯一的,存储在类型对象中,不是存在于实例化的对象中。
static属性不会被GC回收,随着程序的开始而创建,结束而销毁
因此,需要适当使用单例模式。
2.私有静态对象,用于实例化当前类。
3.公有的静态函数或属性,方便其它对象获取该单例类。
实现方式
1.饿汉式
创建时机:饿汉式单例是在程序开始的时候对static属性的Instance进行初始化
安全性:线程安全,static构造函数只可能运行一次
存在空引用的风险,可能运行顺序关系两个类同时引用此单例,就会出现空引用错误。
2.懒汉式
确保只创建一个单例,只需要实例时创建;
变量用volatile声明,确保在访问实例变量前完成对实例变量的赋值
使用locker实例上锁,而不是锁住对象本身,避免死锁
避免了多个对象同时访问实例对象的时候报空引用。
懒汉式延迟了实例化,直到对象第一次被访问
3.通用类
4.Mono通用类单例
不能用new实例化,需要挂载在场景中的游戏对象上
在脚本生命周期的Awake函数中初始化
无需担心因Awake等调用顺序造成的空指针异常
1.饿汉式
public class Singleton
{
//私有构造函数
private Singleton(){}
//私有对象
private static Singleton instance;
//公有对象
pubic static Singleton Instance
{
get
{
if(null==instance)
{
instance=new Singleton;
}
return instance;
}
}
}
2.懒汉式
/// <summary>
/// 懒汉式单例模式通用父类
/// </summary>
public class SingletonLazy
{
//私有构造函数
private SingletonLazy() { }
//私有对象
private static volatile SingletonLazy instance;
private static object locker = new object();
//公有对象
public static SingletonLazy Instance
{
get
{
if (instance == null)
{
lock (locker)
{
if (instance == null)
{
//确保只调用一次
instance = new SingletonLazy();
}
}
}
return instance;
}
}
}
3.通用类单例
namespace Common
{
public class Singleton<T> where T : class, new()
{
private static T _instance;
private static readonly object syslock = new object();
public static T Instance
{
get
{
if (_instance == null)
{
lock (syslock)
{
if (_instance == null)
{
_instance = new T();
}
}
}
return _instance;
}
}
}
}
4.Mono通用类单例
using UnityEngine;
namespace Common
{
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public static T Instance
{
get
{
return _instance;
}
}
protected virtual void Awake()
{
_instance = this as T;
}
}
}