文章导航PC6首页软件下载单机游戏安卓资源苹果资源

pc软件新闻网络操作系统办公工具编程服务器软件评测

安卓新闻资讯应用教程刷机教程安卓游戏攻略tv资讯深度阅读综合安卓评测

苹果ios资讯苹果手机越狱备份教程美化教程ios软件教程mac教程

单机游戏角色扮演即时战略动作射击棋牌游戏体育竞技模拟经营其它游戏游戏工具

网游cf活动dnf活动lol周免英雄lol礼包

手游最新动态手游评测手游活动新游预告手游问答

您的位置:首页单机游戏角色扮演 → 怪物猎人世界新装备介绍 怪物猎人世界新装备新系统一览

iOS开发单例使用问题

翻译、修改自obj.io

单例(Singletons),是Cocoa的核心模式之一。在iOS上,单例十分常见,比如:UIApplication,NSFileManager等等。虽然它们用起来十分方便,但实际上它们有许多问题需要注意。所以在你下次自动补全dispatch_once代码片段的时候,想一下这样会导致什么后果。

在《设计模式》一书中给出了单例的定义:

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式提供了一个访问点,供客户类为共享资源生成唯一实例,并通过它来对共享资源进行访问,这一模式提供了灵活性。

在objective-c中,可以使用以下代码创建一个单例:

+(instancetype)sharedInstance

{

static dispatch_once_t once;

static id sharedInstance;

dispatch_once(&once, ^{

sharedInstance = [[self alloc]init];

});

return sharedInstance;

}

当类只能有一个实例,而且必须从一个访问点对其进行访问时使用单例就显得十分方便,因为使用单例保证了访问点的唯一、一致且为人熟知。

全局状态

首先我们都应该达成一个共识"全局可变状态"是危险的,因为这样会让程序变得难以理解和调试,就削减状态性代码上,面向对象编程应该向函数式编程学习。

比如下面的代码:

@implementation Math{

NSUInteger _a;

NSUInteger _b;

-(NSUInteger)computeSum

return _a + _b;

这段代码想要计算_a和_B相加的和,并返回。但事实上这段代码存在着不少问题:

computeSum方法中并没有把_a和_b作为参数。相比查找interface并了解哪个变量控制方法的输出,查找implementation来了解显得更隐蔽,而隐蔽代表着容易发生错误。

当准备修改_a和_b的值来让它们调用computeSum方法的时候,程序员必须清楚修改它们的值不会影响其他包含着两个值的代码的正确性,而在多线程的情况下作出这样的判断显得尤其困难。

对比下面这段代码:

+(NSUInteger)computeSumOf:(NSUInteger)a plus:(NSUInteger)b

return a + b;

这段代码中,a和b的从属显得十分清晰,不再需要去改变实例的状态来调用这个方法,而且不用担心调用这个方法的副作用。

那这个例子和单例又有什么关系呢?事实上,单例就是披着羊皮的全局状态。一个单例可以在任何地方被使用,而且不用清晰地声明从属。程序中的任何模块都可以简单的调用[MySingleton sharedInstance],然后拿到这个单例的访问点,这意味着任何和单例织梦悬浮文插件位置_最强资讯网交互时产生的副作用都会有可能影响程序中随机的一段代码,如:

@interface MySingleton : NSObject

+(instancetype)sharedInstance;

-(NSUInteger)badMutableState;

-(void)setBadMutableState:(NSUInteger)badMutableState;

@end

@implementation ConsumerA

-(void)someMethod

if([[MySingleton sharedInsthtml5 ie8不支持_最强资讯网ance] badMutableState]){

//do something...

@implementation ConsumerB

-(void)someOtherMethod

[[MySingleton sharedInstance] setBadMutableState:0];

在上面的代码中,ConsumerA和ComsumerB是程序中两个完全独立的模块,但是ComsumerB中的方法会影响到ComsumerA中的行为,因为这个状态的改变通过单例传递了过去。

在这段代码,正是因为单例的全局性和状态性,导致了ComsumerA和ComsumerB这两个看起来似乎毫无关系的模块之间隐含的耦合。

另一个单例的主要问题是它们的生命周期。

举个例子,假设一个app中需要实现能够让用户看到他们的好友列表的功能,每一个好友有自己的头像,同时我们还希望这个app能够下载并缓存这些好友的头像。这时候通过之前学习单例的知识,我们很可能会写出以下的代码:

@interface MyAppCache : NSObject

+(instancetype)sharedCMyAppCache;

-(void)cacheProfileImage:(NSData *)imageData forUserId:(NSString *)userID;

-(NSData *)cachedProfileImageForUserId:(NSString *)userId;

这段代码看起来完全没有问题,运行起来也很好,所以app继续开发,直到有一天,我们决定帮app加入"登出"的功能。突然我们发现,用户数据储存在全局单例中。当用户登出的时候,我们想要把这些数据清除掉,当新用户登入的时候,再为他创建一个新的MyAppCache。

但是问题出在了单例这里,因为单例的定义就是:"创建一次,永久存活"的实例。事实上有很多方法解决上面的问题,我们也许可以在用户登出的时候销毁这个单例:

static MyAppCache *myAppCache;

+(instancetype)sharedMyAppCache

ifideacentre k450怎么拆_最强资讯网(!myAppCache)

myAppCache = [[self alloc] init];

return myAppCache;

+(void)tearDown

myAppCache = nil;

上面的代码扭曲了单例这个模式,但是能起到作用。

事实上的确可以使用这个方法来解决这个问题,但是代价太大了。最重要的一点是我们放弃了dispatch_once,而它正是保证了方法调用时候的线程安全,现在所有调用[MyAppCache shareMyAppCache]的代码都会得到同一个变量,着需要清楚使用MyAppCache代码执行的顺序。试想一下当用户在登出的时候碰巧后台调用了这个方法来保存图片。

另一方面,实行这个方法需要确保tearDown这个方法不会在后台任务还没执行完成的时候调用,或者说确保执行tearDown方法的时候后台任务都会被取消。否则另一个新的MyAppCache将会创建,并把陈旧的数据保存进去。

但是由于单例没有明确的owner(因为单例自己管理自己的生命周期),销毁一个单例是非常艰难的。

所以这时你可能会想,"那就不要把MyAppCache做成单例吧!"其实问题在于一个对象的生命周期在项目初期可能没有办法很好的确定,如果假设一个对象的生命周期将会匹配整个程序的生命周期,这将会大大限制了代码的可拓展性,当产品需求改动的时候这将会很痛苦。

所以上面的一切都是为了阐明一个观点:"单例只应该保持全局状态,且该状态php开发实战视频_最强资讯网的生命周期与程序的生命周期一致"。对于程序中已经存在的单例,需要批判性的审阅。

关于这一部分原文中放到了上一章节中提及,但我认为在软件开发中测试是十分重要的一环,所以单独把这一块的内容另开一个章节,并加入一些个人的见解。

由于单例一直在整个app的生命周期中存活着,甚至在执行测试的时候也一直存活着,这导致了在一个测试或许会影响另一个测试,这是在单元测试中的大忌。

所以有必要在进行单元测试的时候能够有效销毁一个单例,并保持住单例线程安全的特性。但在上文中我提到:

"但是由于单例没有明确的owner(因为单例自己管理自己的生命周期),销毁一个单例是非常艰难的。"

似乎两者在自相矛盾,其实不然,可以选择简化单例,与其拥有各种的单例,不如只拥有一个"真正的" 单例ServiceRegistry,而把其他"潜在的"单例来被ServiceRegistry引用,这样其他单例拥有了一个owner升级win10玩wow画面卡顿_最强资讯网,能够在进行单元测试的时候能够及时对单例进行销毁,保证了单元测试的独立性。

另一方面,ServiceRegistry的存在使得其他"单例"不再是单例,这样在TDD的时候会让之前难以 mock 的单例变得更加简单的 mock 。

我们都知道全局可变状态是不好的,但是在使用单例的时候我们又不经意地把它变成我们讨厌的全局可变状态。

在面向对象编程中,我们需要尽可能减少可变状态的作用域,而单例与这个思想背道而驰,希望在下一次使用单例的时候能够多想一想,考虑是否这个变量真正值得成为一个单例,如果不是,还请使用"依赖注入模式"来代替。

CocoaChina开发者社区本着为广大移动开发者提供资讯、问答服务,现向广大开发者们征稿,欢迎有写作爱好和生活经历的开发者们踊跃投稿,来稿范围可设计行业动态,技术相关,产品应用jquery ui combobox 取值_最强资讯网等等,体裁篇幅不限。本征稿启事长期有效。投稿请发送到:

当前文章:http://3123294.emilyseyelive.com/20171208/fa981_10946.html

发布时间:2018-02-19 17:04:46

ecshop 模板  多次点击android版本出现错误  锋利的jquery第二版源码  netframework4 32  photoshop图片更改  unity教程下载  android开发板改进  织梦悬浮文插件位置  adobe photoshop cs5序列号及破解方法  html5游戏下载工具  c++ 两个字符串比较  python 自然语言处理 urlopen  android 开发环境 2015  com.android.backupconfirm  php程序培训班  

相关阅读 史上最宽高校落户政策,外地毕业生如何成为一名西安人?PS野教程:简单几步,教你把人物放进硬币里同是不被宋丹丹看好的"子女",杨紫大红大紫,他却被轰下舞台!必看!2017黑龙江省体育赛事全攻略,我敢办赛!你敢参加吗?夏季去漠河旅游行程路线怎么走?有什么好玩的?有哪些必到景点?学纹绣有前途吗?纹绣师就业前景剖析?每天给宝宝吃鸡蛋,可你知道怎么吃才最安全、最营养吗?(附6种不同鸡蛋辅食做法...35元真时尚?张柏芝买最贵鞋子遭家中佣人嫌弃

文章评论
发表评论

热门文章 《长歌行》作者夏达称自己"受够了"夏天岛签约漫画家遭遇了啥?洋品牌取个好中文名有多重要?可口可乐曾叫"蝌蚪啃蜡","奔驰"曾用名叫"笨死"全球首次解禁:2017年最新丰胸秘籍是酒酿蛋吗?刚过去的520被虐了吗?不想在被虐快快戴块粉晶招桃花吧

最新文章 中国留学生帮熟人转个账竟面临牢狱之灾?有偿带物被判死刑?表脸!一父亲带女儿逛上海书城假装找书疑似偷拍裙底 挖笋:锄尖欢乐,变为心灵放飞和田玉碧玉怎么挑最好?让我们带着实例给大家介绍下2017综艺排名:第一名实至名归,《跑男》竟倒数?周一见卓伟爆白百何陈羽凡砸车后续内幕,疑似小鲜肉吸毒曝光了?

人气排行 重温国学大师梁漱溟对我们"民族品性"的十点总结,你有何感想?市三中将在花城新区开分校?幼儿园实施营养餐…2017年,攀枝花教体工作亮点居...2岁儿童适合泡温泉吗?和田玉有哪些雕刻题材是守护保平安的?--五柳珠宝消防员父亲来京探望儿子走失老人患间歇性老年痴呆准备好迎接5G时代了吗?中国移动5G实验室落户重庆奇瑞果然崛起了,全新SUV外观完爆博悦,性价比超高售价仅8万!深闺藏瑜璟,岂顾冷清洲?卓伟又写诗了不过这次的周一见太弱

http://www.800666666.comhttp://www.adkimaging.comhttp://www.afcustoms.comhttp://www.agrobag.nethttp://www.alitlbetr.comhttp://www.aynaammar.comhttp://www.bytemyfood.comhttp://www.chevybiz.comhttp://www.dangerjesus.comhttp://www.decliffinn.comhttp://www.diffussion.comhttp://www.e-zrental.comhttp://www.evolv-ed.comhttp://www.fredennis.comhttp://www.jerseysza.comhttp://www.51happygo.comhttp://www.beikao360.comhttp://www.cbd518.comhttp://www.chanpinb2b.comhttp://www.export23.comhttp://www.fishnn.comhttp://www.frenchinawine.comhttp://www.gzxinchang.comhttp://www.ieduok.comhttp://www.isportskong.comhttp://www.moniocho.comhttp://www.qydown.comhttp://www.thrksw.comhttp://www.xibucn.comhttp://www.xylbgs.comhttp://www.zhongyiwuliu.comhttp://www.mmwcycling.comhttp://www.quoiquand.comhttp://www.sa-survival.comhttp://www.wxtbzd.ushttp://www.hmuylg.ushttp://www.wjbotr.ushttp://www.gpkppz.ushttp://www.zfjhiv.ushttp://www.tysokr.ushttp://www.ebcdat.ushttp://www.kqflyt.ushttp://www.xaixwa.ushttp://www.jfjutv.ushttp://www.gxgkgy.ushttp://www.bjjazr.ushttp://www.cytbms.ushttp://www.wlrfvs.ushttp://www.ftryjy.ushttp://www.newsus.com.cn/aoefmy8za/index.html|663365000