单例模式在Unity中的应用
起因:每个游戏场景中都会有许多的游戏对象,而各个游戏场景之间也是同等的关系。如何去管理它们,是我们要解决的问题。
场景中各脚本间的直接访问,会在各脚本间形成一个巨大而又混乱的网络,这给以后代码的维护带来了极大的困难。为了避免这种因交互访问而带来的过度耦合情况,我们取消掉场景中各脚本间的直接交互,取而代之的是,让所有脚本都只与场景中的一个特定脚本交互。
在刚开始使用这种方法时,自己声明了一个场景中的全局脚本,然后把场景中所有其他需要交互的脚本声明为其成员,一旦脚本间要发生交互,就在脚本中声明一个全局脚本的对象,然后通过这个对象去访问其他的脚本,从而把直接交互变成了间接交互。这样做确实解决了脚本之间直接访问带来的高耦合度问题,但是在每个脚本中都要保存一个全局脚本的对象,这显然有些不太合适,浪费了资源。为了进一步解决这个问题,引入了单例模式的应用。
单例模式的定义是:保证一个类只有一个实例,并且提供一个访问它的全局访问点。单例对象的类必须保证只有一个实例存在。在我们的场景中,全局脚本的对象只会创建一次,保证单例,然后它(全局单例类)提供给各个脚本访问单例对象的方法,并且所有其他脚本的公共数据都会存储在全局单例脚本中。
private static GloSingleton _globalSingleton;
声明全局单例类自身类型的静态私有成员变量,作为单例对象使用。
public static GloSingletonGetSingleton() { …}
提供获取单例对象的类的静态方法。任何对单例对象的访问都要通过该方法来获取。
if (null ==_globalSingleton) {
lock(_globalSingleton) {
if(null == _globalSingleton) {
_globalSingleton=
(GloSingleton)GameObject.FindObjectOfType(typeof(GloSingleton));
}
}
}
单例模式的使用在多线程并发的情况下必须小心谨慎。因为当唯一实例尚未创建时,如果有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自会创建一个实例,这违背了单例模式中实例唯一的原则。解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁。
如我们的代码所示,在方法内部,首先判断单例对象是否为空,为空的话说明单例对象还没有创建,需要实例化一个。反之直接返回单例对象。在准备首次创建单例对象时,设置了一个互斥锁。目的是为了在多线程并发的情况下也能保证单例。相关内容请参看我转载的另一篇博文《C#中的lock关键字》。互斥锁中的判空检测同样是为了保证单例而设的。如果没有二次的检测,当线程A进入lock代码块中,线程B等待时,刚开始单例对象还没有创建,线程A执行完毕离开lock代码块后,单例对象已被创建完毕,而此时原本等待的线程B会进到lock代码块中,再次创建单例对象,因此单例被破坏。二次检测则避免了这种情况的发生。当线程A从lock中离开时,单例对象已经存在,线程B进入lock,便不会再执行创建单例对象的代码了。
这种实现方式即遵守了单例模式,又不必在每次获取单例对象时进行互斥锁的判断,提高了效率。因为自己对单例模式的理解比较简单,若大家有更好的实现方法,欢迎交流讨论。
单例模式在Unity中的应用的更多相关文章
- Unity中C#单例模式使用总结
一.单例模式优点 单例模式核心在于对于某个单例类,在系统中同时只存在唯一一个实例,并且该实例容易被外界所访问: 意味着在内存中,只存在一个实例,减少了内存开销: 二.单例模式特点 只存在唯一一个实例: ...
- 【Unity3D基础教程】给初学者看的Unity教程(七):在Unity中构建健壮的单例模式(Singleton)
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! 该博客中的代码均出自我的开源项目 : 迷你微信 ...
- MonoSingleton——Unity中的单例模式
Unity中有很多特别的类需要以单例模式呈现,比如全局的UI管理类,各种缓存池,以及新手导航类等等.而Unity中,因为所有继承自Monobehaviour的脚本在实现的时候都是单线程的,所以像网上流 ...
- Unity中的万能对象池
本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的万能对象池 本节通过一个简单的射击子弹的示例来介 ...
- 【《Effective C#》提炼总结】提高Unity中C#代码质量的21条准则
作者:Williammao, 腾讯移动客户端开发工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/290.h ...
- 【《Effective C#》提炼总结】提高Unity中C#代码质量的22条准则
引言 原则1尽可能地使用属性而不是可直接访问的数据成员 原则2偏向于使用运行时常量而不是编译时常量 原则3 推荐使用is 或as操作符而不是强制类型转换 原则4 推荐使用条件属性而不是if条件编译 原 ...
- 【转】Effective C#观后感之提高Unity中C#代码质量的21条准则
转自:http://blog.csdn.net/swj524152416/article/details/75418162 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effectiv ...
- Unity编程标准导引-3.4 Unity中的对象池
本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的对象池 本节通过一个简单的射击子弹的示例来介绍T ...
- Unity中使用Attribute
Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...
随机推荐
- Winform Windows Media Player 简易播放器 分类: WinForm 2014-07-31 20:12 589人阅读 评论(0) 收藏
新手上路,高手勿进! 窗体设计: 实现效果: 实现代码: using System; using System.Collections.Generic; using System.ComponentM ...
- 【设计模式 - 8】之组合模式(Composite)
1 模式简介 组合模式可以将对象以树形结构来表现"整体/部分"层次结构,让客户以一致的方式处理个别形象以及对象组合. 组合模式让我们能用树形方式创建对象的结构,树里面包含 ...
- php开发工具zendstudio13破解补丁
io? Intelligent Code Editor Robust Debugging Capabilities Eclipse Ecosystem Mobile: AngularJS, Ioni ...
- HDU ACM 1025 Constructing Roads In JGShining's Kingdom->二分求解LIS+O(NlogN)
#include<iostream> using namespace std; //BFS+优先队列(打印路径) #define N 500005 int c[N]; int dp[N]; ...
- 详解 Spring 3.0 基于 Annotation 的依赖注入实现--转载
使用 @Repository.@Service.@Controller 和 @Component 将类标识为 Bean Spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的 ...
- css考核点整理(四)-css盒模型
http://paranimage.com/css-box-model/
- ip、数字的互转
# ip ==> 数字 >>> ip2num = lambda x:sum([256**j*int(i) for j,i in enumerate(x.split('.')[: ...
- jQuery Capty 图片标题插件
jQuery Capty是可以为图片添加漂亮的字幕的插件 文件包含: <link type="text/css" rel="stylesheet" hre ...
- POS tagging的解釋
轉錄文章~~ 什么是词性标注(POS tagging) Tue, 04/13/2010 - 10:36 — Fuller 词性标注也叫词类标注,POS tagging是part-of-speech t ...
- Less 关于css hack的写法
由于工作需要,最近一直在弄css转写less,遇到最多的问题就是 hack的写法,一些IE的hack,less不支持编译: 常见的不支持的hack如下: IE的滤镜写法 \9\0 IE8部分支持 ...