Unity 单例模式
明天十一放假,今天不知什么原因看到一篇unity单例模式的介绍,瞬间来了戾气。
(一)最简单的单利
public class WebRequestUtility : MonoBehaviour
{
public static WebRequestUtility Instance; private void Awake()
{
Instance = this;
}
}
这是最简单有效,最实用最没问题的单利模式。如果说存在什么问题,那就是在别的脚本awake中引用,若果其他脚本中的awake比上述awke先执行,则会报空引用。此问题通过设置脚本执行顺序课解决。题外话,一般初始化启动尽量用start,除非是非常确定要先运行用awake,不要为了先执行而用awake;
(二)构造函数法
public class WebRequestUtility : MonoBehaviour
{
public static WebRequestUtility Instance; WebRequestUtility()
{
Instance = this;
} }
构造函数中初始化instance最先执行,会在awake之前(官方为找到直接说明,但是鉴于脚本先初始化而后运行,会比awake先执行,事实也是这样,如果有人发现有问题再议,来互怼)。但在2017unity版本中遇到过bug(紧遇到一次),即刚开始运行时,构造函数多次运行,原因未找到。
(三)DontDestroyOnLoad情况下的单例模式
有时候单例不能随着场景的加载而消失,需要一直存在,所以需要不能销毁,但是加载时场景中就会存在两个单例(这个说法本身有问题,即本来已经有单例,但是在场景加载时awake又重新运行的情况)
public class WebRequestUtility : MonoBehaviour
{
public bool bDontDestroyOnLoad = false; public static WebRequestUtility Instance; private void InitializeInstance()
{
if (Instance != null & Instance == this)
return; if(bDontDestroyOnLoad)
{
if(Instance==null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
else
{
Instance = this;
}
} private void Awake()
{
InitializeInstance();
}
}
上述代码参考自unity的NetworkManager组件的源代码。逻辑很简单,只允许有一个单例,引用时,除了保证单例已经初始化(不为空),还要保证单例==this。否则就是单例被重新赋值了,即在别的地方又重新初始化,既然使用单例模式这是不允许的。
(四)静态属性或者静态方法法
public class WebRequestUtility : MonoBehaviour
{
private static WebRequestUtility instance; public static WebRequestUtility Instance
{
get
{
if(instance==null)
{
instance = new WebRequestUtility();
} return instance;
}
}
}
这种也是一种比较好的方法,但是没有(一)(二)简洁,一般用于获取单例时需要再初始化等问题时,对于大部分单例模式(一)(二)已经够用。
(四)单例模式乱象(真正互怼开始)
本想再这部分直接开始怼的,但是写到这人戾气已经没了,还是好好学习的好啊,学习让我心平气和。继续说某度出的unity单例的问题。
1)单例变”多例“
从他代码角度确实时要单例,但是经过几行代码后变成多例,然后又经过几行代码,然后可从多个事例中return一个”单例“(???),本想直接上链接怼的,想想还是算了。可以看看此文https://blog.csdn.net/qq_15267341/article/details/54232854,多简介,多明了。
2)使用锁(lock)
使用锁没有任何问题,但是unity中不推荐使用。再.net中单例模式必须加锁,因为再多线程中统一使用单例会出现冲突等等问题,比如死锁,或者逻辑未理清出问题。但是unity是单线程操作,通过协程来实现“异步“操作,所以不存在此问题。当然也存在开线程的问题,但是开线程或者异步操作只针对纯数据层面的操作,因为在非主线程中是无法进行组件操作的(通俗讲就是操作unity自定义的东西)。所以在unity中异步或者开线程时,基本可以避免在其他线程中调用主线程中的单例情况(针对游戏层面,vr ar来说)。在极少数非要进行相关处理的(一般是在回调时出现),也可以通过在update中实时检测来解决。当然了,如果你的单例不涉及到unity相关组件操作,那也就不用继承mono,就可以用纯C#的语法来处理了。
最后竟然一点戾气都没有了。。。。。。。。。。。。。。。。。。
Unity 单例模式的更多相关文章
- 【转】Unity+单例模式的依赖注入
http://www.cnblogs.com/floyd/archive/2009/06/17/1505117.html
- unity脚本的运行顺序以及单例的实现
unity引擎把所有脚本先行编译后,在运行的时候一批,一批的函数进行执行. unity脚本自带函数执行顺序如下:将下面脚本挂在任意物体运行即可得到 Awake ->OnEable-> St ...
- unity单例封装
# 1.前言本篇主要针对Unity单例模式,完成一个可以重复继承使用的抽象类,减少重复的工作与代码.同时,对存在的多种单例进行优劣分析.# 2.Unity单例问题分析## 2.1 单例原则单例要满足以 ...
- 【Unity3D基础教程】给初学者看的Unity教程(七):在Unity中构建健壮的单例模式(Singleton)
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! 该博客中的代码均出自我的开源项目 : 迷你微信 ...
- 【Unity技巧】使用单例模式Singleton
这几天想把在实习里碰到的一些好的技巧写在这里,也算是对实习的一个总结.好啦,今天要讲的是在Unity里应用一种非常有名的设计模式——单例模式. 开场白 单例模式的简单介绍请看前面的链接,当然网上还有很 ...
- Unity中C#单例模式使用总结
一.单例模式优点 单例模式核心在于对于某个单例类,在系统中同时只存在唯一一个实例,并且该实例容易被外界所访问: 意味着在内存中,只存在一个实例,减少了内存开销: 二.单例模式特点 只存在唯一一个实例: ...
- MonoSingleton——Unity中的单例模式
Unity中有很多特别的类需要以单例模式呈现,比如全局的UI管理类,各种缓存池,以及新手导航类等等.而Unity中,因为所有继承自Monobehaviour的脚本在实现的时候都是单线程的,所以像网上流 ...
- 单例模式在Unity中的应用
起因:每个游戏场景中都会有许多的游戏对象,而各个游戏场景之间也是同等的关系.如何去管理它们,是我们要解决的问题. 场景中各脚本间的直接访问,会在各脚本间形成一个巨大而又混乱的网络,这给以后代码的维护带 ...
- Unity C# 设计模式(一)单例模式
动机(Motivation): 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性.以及良好的效率 意图: 保证一个类仅有一个实例,并提供一 ...
随机推荐
- Scrapy项目 - 源码工程 - 实现豆瓣 Top250 电影信息爬取的爬虫设计
一.项目目录结构 spiders文件夹内包含doubanSpider.py文件,对于项目的构建以及结构逻辑,详见环境搭建篇. 二.项目源码 1.doubanSpider.py # -*- coding ...
- java-newInstance()和new()
public <T> T genericMethod(Class<T> tClass)throws InstantiationException , IllegalAccess ...
- Spring 梳理 - 视图解析器 VS 视图(View,ViewResolver)
View View接口表示一个响应给用户的视图,例如jsp文件,pdf文件,html文件等 该接口只有两个方法定义,分别表明该视图的ContentType和如何被渲染 Spring中提供了丰富的视图支 ...
- SpringBootSecurity学习(12)前后端分离版之简单登录
前后端分离 前面讨论了springboot下security很多常用的功能,其它的功能建议参考官方文档学习.网页版登录的形式现在已经不是最流行的了,最流行的是前后端分离的登录方式,前端单独成为一个项目 ...
- 【ADO.NET基础-Login】带验证码验证的登录界面(用于简单的基础学习)
以下代码如果有不对或者不妥之处,还望大神们指点一二 或者有同学者有问题或建议,一定要提出来,共同探讨 小弟在此感谢! 前台代码: <!DOCTYPE html> <html xmln ...
- mysql操作遇到的坑(第一版)
1.当我们要统计数据表数量时,如果遇到多表查询,会出现一个主表对应多个子表的维度,我们会用到group by,但是不要再用统计函数去操作数据,因为统计还是会统计原数据 案例 SELECT sum(`o ...
- 瀑布流实例及懒加载(echo.js)
瀑布流布局: 图片等宽,不定高,按最低高度来顺序排列:实现方法:获取每次获取四行中最低高度对应的一行,将下一张加载的图片放在该位置,每次加载前都获取最低高度: ①请求图片的接口 地址此php文件 ...
- 学Python的第一天
第一天学习笔记 一.安装typroa 下载软件typroa用于日常学习笔记记录,该软件支持markdown语法 步骤: 官网地址:https://typora.io/ 选择版本安装(以windows为 ...
- 原生js使用getComputedStyle方法获取CSS内部属性值
在对网页进行调试的过程中,经常会用到js来获取元素的CSS样式, 1.下面的方法只能JS只能获取写在html标签中的写在style属性中的值(style=”…”),而无法获取定义在<style ...
- Django2.1.3 urls.py path模块配置
learning_log/urls.py learning_logs/urls.py django2.0和1.x的区别是非常明显的,2.0开始使用path和re_path代替原来的url,而且用法有了 ...