当前位置: 首页 > news >正文

Unity 单例模式

Unity中单例模式是非常常用的写法,可以基于C#语言的几种不同方法来实现。
下面我将列出几种常见的实现方式:

1. 经典的单例模式

public class SingletonExample : MonoBehaviour
{private static SingletonExample instance;public static SingletonExample Instance{get{if (instance == null){instance = FindObjectOfType<SingletonExample>();if (instance == null){GameObject obj = new GameObject("SingletonExample");instance = obj.AddComponent<SingletonExample>();DontDestroyOnLoad(obj);}}return instance;}}private void Awake(){if (instance == null){instance = this;DontDestroyOnLoad(this.gameObject);}else if (instance != this){Destroy(gameObject);}}
}

优点:

  • 易于理解和实现。
  • 可以在Unity的场景中直接使用,提供了与Unity生命周期事件的结合。

缺点:

  • 不是完全的线程安全。在多线程环境下,可能会创建多个实例。
    如果没有在场景中找到实例,它会创建一个新的GameObject,这可能会导致意外的副作用。

2. 使用静态构造函数

public class SingletonExample
{private static readonly SingletonExample instance = new SingletonExample();static SingletonExample(){}private SingletonExample(){}public static SingletonExample Instance{get{return instance;}}
}

优点:

  • 实现简单,线程安全由CLR (公共语言运行时)保证。
  • 静态构造函数只会被执行一次,保证了实例的唯一性。

缺点:

  • 实例在程序运行时立即创建,无论是否使用,可能会导致资源的浪费。
    不适合在Unity场景对象中使用,因为它与MonoBehaviour断开了联系,不能直接应用到GameObject上。

3. 使用Lazy类型确保线程安全

using System;public class SingletonExample
{private static readonly Lazy<SingletonExample> lazy =new Lazy<SingletonExample>(() => new SingletonExample());public static SingletonExample Instance { get { return lazy.Value; } }private SingletonExample(){}
}

优点:

  • 实现简单,线程安全由CLR (公共语言运行时)保证。
  • 静态构造函数只会被执行一次,保证了实例的唯一性。

缺点:

  • 实例在程序运行时立即创建,无论是否使用,可能会导致资源的浪费。
    不适合在Unity场景对象中使用,因为它与MonoBehaviour断开了联系,不能直接应用到GameObject上。

4. 双重校验锁(Double-Check Locking)

public class SingletonExample
{private static SingletonExample instance;private static readonly object lockObject = new object();public static SingletonExample Instance{get{if (instance == null){lock (lockObject){if (instance == null){instance = new SingletonExample();}}}return instance;}}private SingletonExample(){}
}

优点:

  • 线程安全,并且在需要时才创建实例。
  • 相对于Lazy,在早期的.NET版本中也可以使用。

缺点:

  • 实现复杂,需要正确管理锁,否则可能会导致死锁。
  • 性能开销,每次访问实例时都需要进行双重检查。
  • 不直接与MonoBehaviour兼容,同样不适合直接应用于Unity场景中的对象。

总结:

在选择实现单例的方法时,应当考虑是否需要延迟初始化、是否在多线程环境中使用、以及是否需要与Unity的MonoBehaviour系统集成等因素。
在Unity中,经常使用第一种方法,因为它能够更好地与Unity的组件和生命周期集成。
不过,如果你在Unity项目中需要使用单例模式管理非MonoBehaviour类型的资源或类,例如数据管理或服务类,那么**第三种方法(Lazy)**是一个非常好的选择。

http://www.lryc.cn/news/346204.html

相关文章:

  • Oracle-一次TX行锁堵塞事件
  • Gtid方式搭建主从复制+MHA高可用集群
  • 基于matlab GUI的Alpha shapes边缘提取
  • [Android]常见的包管理方式
  • 每日10亿数据的日志分析系统OOM
  • 智能驱动,精准管理:打造高效干部管理系统
  • 轮式机器人简介
  • 已知哈夫曼节点个数,求哈夫曼字符编码数
  • Kubernetes Cluster IP,Node IP,Pod IP间通信原理解析
  • 随机链表的深拷贝
  • 328_C++_HTTP_HTTP协议传输data数据,为什么要进行base64编解码操作?
  • 【二叉树】Leetcode N 叉树的层序遍历
  • Spring AI
  • fiori SAP ui5 动态改变控件颜色
  • RabbitMQ php amqp
  • 对称二叉树
  • 浅浅总结SQL中的事务.
  • C++ | Leetcode C++题解之第76题最小覆盖子串
  • 什么可以替代iframe?
  • HTTP/1.0、HTTP/1.1、HTTP/2.0区别
  • 鸿蒙内核源码分析(文件句柄篇) | 你为什么叫句柄
  • 2024.5.8 关于 SpringCloud —— Ribbon 的基本认知
  • Lua 协程模拟 Golang 的 go defer 编程模式
  • maven的安装与配置(超详细)
  • springCloud服务降级使用到的组件
  • Spring框架学习-详细
  • fatal: fetch-pack: invalid index-pack output
  • 相机购买指南
  • STM32微秒级别延时--F407--TIM1
  • AI图书推荐:杀手级ChatGPT提示词——利用人工智能实现成功与盈利