提到框架,大家可能会觉得很复杂,我也是有同感
但好在,也不是所有的框架都需要我们掌握的
但这期提到单例模式却是大家一定要掌握!!!
因为它真的非常重要!!!
这里我整理了三种开发中常用的单例模式基类,希望大家看完后能多敲几遍,把它变成自己的知识
(如果想直接拿到代码的话可以在我上传的资源中搜索单例就可以免费下载)
注:后面的mono指的就是Unity中的MonoBehaviour类
第一种,不继承mono的单例基类(这种自然就无法挂载到GameObject上了)
最大的缺点就是它的构造函数还可以在外部调用,会破坏唯一性
但这一点也可以很好的规避,那就是不去调用它的构造函数(只要懂得单例模式的程序员都不会犯这个问题)
另一种解决方法就是使用反射相关的知识,请大家看第二段代码
/// <summary>
/// 单例模式基类
/// </summary>
/// <typeparam name="T"></typeparam>
public class BaseManager<T>where T: class,new ()
{
private static T instance;
//通过属性获取,任选其一
public static T Instance
{
get
{
if (instance == null)
instance = new T();
return instance;
}
}
//通过属性获取,任选其一
public static T GetInstance()
{
if (instance == null)
instance = new T();
return instance;
}
}
这种写法就可以规避上面提到的问题,但需要注意的是继承此类的类,必须要有一个自己的私有的无参构造函数 (后面的这段代码作为参考)
using System;
using System.Reflection;
using UnityEngine;
/// <summary>
/// 单例模式基类
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class BaseMgr<T>where T: class
{
//继承BaseMgr的子类需要自己创建一个私有的无参构造
private static T instance;
//通过属性获取
public static T Instance
{
get
{
if (instance == null)
{
//利用反射得到私有的无参构造函数 来用于对象的实例化
Type type = typeof(T);
ConstructorInfo info = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic,
null,
Type.EmptyTypes,
null);
if (info != null)
instance = info.Invoke(null) as T;
else
Debug.LogError("没有找到对应的无参构造函数");
}
return instance;
}
}
}
public class TestMgr : BaseMgr<TestMgr>
{
//不继承mono的单例还要声明一个私有的无参构造,为了不让外面调用
private TestMgr() { }
public void TestLog()
{
Debug.Log("测试");
}
}
第二种,继承mono但需要自己进行挂载的单例基类
创建完脚本后还需要自己挂载到需要的GameObject上
using UnityEngine;
/// <summary>
/// 手动挂载的继承mono的泛型单例
/// </summary>
public class SingletonMono<T> : MonoBehaviour where T: SingletonMono<T>
{
private static T instance; // 唯一实例
// 向外提供
public static T Instance
{
get { return instance; }
}
protected virtual void Awake()
{
// 要是不为空,表示已经存在一个单例 销毁
if(instance != null)
{
Destroy(this.gameObject);
}
else
{
// 强转单例
instance = (T)this;
}
}
}
第三种,继承mono但可以自动进行挂载的单例基类
using UnityEngine;
/// <summary>
/// 自动挂载的单例模式基类
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonAutoMono<T> : MonoBehaviour where T : MonoBehaviour
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
//动态创建物体
GameObject obj = new GameObject();
//得到T脚本类名 为对象改名 这样编辑器中观看更明确
obj.name=typeof(T).Name;
//动态添加脚本 记得为instance赋值
instance=obj.AddComponent<T>();
//过场景不移除 保证它在整个游戏生命周期中都存在
DontDestroyOnLoad(obj);
}
return instance;
}
}
}
标签:instance,Unity,static,单例,基类,null,public
From: https://blog.csdn.net/Blueberry124/article/details/142360043