推荐阅读
- CSDN主页
- GitHub开源地址
- Unity3D插件分享
- 简书地址
- 我的个人博客
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
一、前言
首先,说一下,什么是单例模式(Singleton)
。
单例模式是设计模式中常见的一种设计模式,目的是为了让一个类在程序运行期间有且只有一个实例,方便全局访问。
应用在Unity里面,可以用来作为数据类、工具类、实现类,方便脚本调用。
下面,就在Unity中实现单例模式。
二、实现单例模式
2-1、如何实现单例模式
首先,来看一下单例模式的UML图:
实现流程:
1、私有的构造函数,也就是用static静态字段。
static属性在此类中是唯一的,存储在类型对象中,不是存在于实例化出来的对象中。
static属性不会被GC回收,随着程序开始而创建,结束而销毁。
因此,需要适当使用单例模式
2、私有静态对象,用于实例化当前类。
3、公有静态函数或属性,方便其他对象获取这个单例类。
实现方式:
1、饿汉式
2、懒汉式
3、通用类
2-2、实现饿汉式单例模式
参考代码:
/// <summary>
/// 饿汉式单例模式通用父类
/// </summary>
public class Singleton
{
//私有构造函数
private Singleton() { }
//私有对象
private static Singleton instance;
//公有对象
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
饿汉式的单例,是在程序开始的时候对static属性的Instance进行初始化,饿汉式的特征:
- 线程安全,static构造函数只可能运行一次
- 存在空引用的风险,可能运行顺序关系两个类同时引用此单例,就会报空引用错误
2-3、实现懒汉式单例模式
参考代码:
/// <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;
}
}
}
懒汉式单例,确保只创建一个实例,只需要实例时创建,懒汉式的特征:
- 变量用volatile声明,确保在访问实例变量之前完成对实例变量的赋值
- 使用locker实例来上锁,而不是锁住类型本身,避免死锁
懒汉式是在饿汉式的基础上优化而来,是为了避免多个对象同时访问实例对象的时候报空引用。
而且懒汉式还可以延迟实例化,直到对象被第一次访问。
多数情况下用饿汉式单例模式实现就可以。
2-4、实现通用类单例模式
上述例子,只是实现单个类的单例模式,在实际开发中会出使用更多的单例,就可以使用一个通用单例父类进行单例实现,子类继承单例父类,就可以继承单例模式,提高代码简洁度。
实现通用单例类可以使用泛型,参考代码:
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;
}
}
}
}
使用方式:
public class UseSingleton : Singleton<UseSingleton>
{
public string Name;
public int Age;
}
单例类
继承实现单例模式的父类Singleton
。
using UnityEngine;
public class CallSingleton : MonoBehaviour
{
void Start()
{
// 修改单例类的变量值
UseSingleton.Instance.Name = "张三";
}
}
脚本去调用或修改单例类中变量的值。
2-5、实现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;
}
}
}
Mono脚本的单例相比较于普通C#单例有一些变化点:
- 不能用new实例化,需要挂载到场景中的对象上
- 在脚本生命周期的Awake函数中初始化
- 无需担心因Awake等调用顺序造成的空指针异常
使用方式:
public class UseSingleton : MonoSingleton<UseSingleton>
{
public string Name;
public int Age;
}
调用:
using UnityEngine;
public class CallSingleton : MonoBehaviour
{
void Start()
{
// 修改单例类的变量值
UseSingleton.Instance.Name = "张三";
}
}
需要将UseSingleton.cs脚本挂载到场景中的对象上,如果不继承Mono就不用挂载到场景中的对象上。
三、后记
本篇文章介绍了什么是单例模式,以及如何实现单例模式。
以及单例模式的饿汉式和懒汉式的区别。
以及在Unity中如何使用单例模式。
最后修改代码制作通用单例模式父类,其他子类继承后就可以实现单例模式。
通用单例模式有两种类型:
- 不继承Mono的单例模式
- 继承Mono的单例模式
你的点赞就是对博主的支持,有问题记得留言:
博主主页有联系方式。文章来源:https://www.toymoban.com/news/detail-783591.html
博主还有跟多宝藏文章等待你的发掘哦:文章来源地址https://www.toymoban.com/news/detail-783591.html
专栏 | 方向 | 简介 |
---|---|---|
Unity3D开发小游戏 | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 |
Unity3D从入门到进阶 | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 |
Unity3D之UGUI | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 |
Unity3D之读取数据 | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 |
Unity3D之数据集合 | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 |
Unity3D之VR/AR(虚拟仿真)开发 | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 |
Unity3D之插件 | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 |
Unity3D之日常开发 | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 |
Unity3D之日常BUG | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |
到了这里,关于【Unity3D日常开发】Unity3D中实现单例模式详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!