iOS 8:dispatch_once解惑

关键字:GCD  dispatch_once  单例  线程安全  double-check

  以前在Java、C#等语言中,我们实现迟缓加载的单例模式一般写成如下形式(伪代码):

private MyClass() {...} // 私有化构造方法

private static MyClass instance; // 承载对象的变量

pubic static MyClass getInstance() { // 完成实例化任务

  if (instance == null) { // 第一次判断

    lock (obj) { // 加锁,处理多线程判断

      if (instance == null) {// 再次判断,避免线程切换导致多个实例对象出现

        instance = new MyClass(); // 完成最终实例化过程

      }

    }

  }

  return instance;
}

  但是,在Objective-C中经常看到的却是这种写法:

+ (instancetype)sharedInstance {

  static id sharedInstance;

  static dispatch_once_t onceToken;

  dispatch_once(&onceToken, ^{

    sharedInstance = [self new];

  });

  return sharedInstance;

}

  这种写法似乎并没对多线程编程作防御性处理。在sharedInstance = [self new];前后加入日志输出,可发现,即使在多线程环境下,dispatch_once也只执行一次。

  其实,dispatch_once是线程安全的,即使在多个线程中同时调用,也只有一个块被执行,其它dispatch_once块的调用被阻塞,直到执行的那个块运行结束,所以在整个程序运行周期内,dispatch_once块只会运行一次,可以确定,下一行代码执行前,整个dispatch_once块是执行完毕的,不管当前工作线程是哪个。如果已执行,dispatch_once会被快速跳过,在类似循环体中调用这种场合,也无需担心执行它的额外性能开销。如果一个程序包含多个同一调用类的实例,只有其中一个实例会执行dispatch_once块[1]

参考:

[1]. Rob Napier 等著, 美团移动 译. iOS编程实战. 北京, 人民邮电出版社. 358~359页

时间: 2024-10-25 12:31:45

iOS 8:dispatch_once解惑的相关文章

IOS 使用dispatch_once 创建单例

+ (instantClass *)sharedClient { static instantClass *_sharedClient = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedClient = [[instantClass alloc] init]; }); return _sharedClient; } IOS 使用dispatch_once 创建单例,码迷,mamicode.co

(译)iOS Code Signing: 解惑

子龙山人 Learning,Sharing,Improving! (译)iOS Code Signing: 解惑 免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作! 原文链接地址:http://www.raywenderlich.com/2915/ios-code-signing-under-the-hood 注:本文由翻译团队成员skingTr

IOS常见语法解惑

由于工作过程中经常需要查看IOS的Objective-C代码,遂把一些常见的.有疑问的OC语法列出,方便之后会看,提升效率. Objective-C中的@语法 @interface告诉编译器,我要声明一个新类,包含了类的属性和方法,以@end结尾: @implementation告诉编译器,这是某个类的具体实现,以@end结尾: @property是声明属性的语法,它可以快速方便的为类的成员变量创建存取器,并允许我们通过点语法使用存取器,@property等同于在.h文件中声明实例变量的get/

iOS 利用dispatch_once创建单例

无论是爱还是恨,你都需要单例.实际上每个iOS或Mac OS应用都至少会有UIApplication或NSApplication. 什么是单例呢?Wikipedia是如此定义的: 在软件工程中,单例是一种用于实现单例的数学概念,即将类的实例化限制成仅一个对象的设计模式. 或者我的理解是: 单例是一种类,该类只能实例化一个对象. 尽管这是单例的实际定义,但在Foundation框架中不一定是这样.比如NSFileManger和NSNotificationCenter,分别通过它们的类方法defau

iOS Code Signing: 解惑详解

原文链接地址:http://www.cnblogs.com/andyque/archive/2011/08/30/2159086.html iPhone开发的代码签名 代码签名确保代码的真实以及明确识别代码的来源.在代码运行在一个开发系统以前,以及在代码提交到Apple发布以前,Apple要求所有的的应用程序都必须进行数字签名.另外,Apple在发布每一个应用程序之前都要添加他自己的数字签名. 数字签名和签名标识 Apple要求所有的iphone应用程序都需要使用apple提供给已注册的ipho

iOS Code Signing: 解惑

注:本文由翻译团队成员skingTree翻译. 教程截图: 下面是一篇有澳洲墨尔本的一名全职iOS开发者提供的文章.他在论坛上是一个很摩登的年轻人 – Adam Eberbach. ·Bundle identifier ·provisioning profiles ·App ID ·certificate signing request 对于新手,的确很难一口气搞清楚这些东东到底有什么区别. 下面我们来揭开它们的神秘面纱,在读完这篇文章后,你应该可以把这些东西联系起来,你能够理解它们是怎么工作,

iOS Provisioning Profile(Certificate)与Code Signing详解

摘自:http://blog.csdn.net/phunxm/article/details/42685597 引言 关于开发证书配置(Certificates & Identifiers & Provisioning Profiles),相信做 iOS 开发的同学没少被折腾.对于一个 iOS 开发小白.半吊子(比如像我自己)抑或老兵,或多或少会有或曾有过以下不详.疑问.疑惑甚至困惑: 什么是App ID?Explicit/Wildcard App ID有何区别?什么是App Group

iOS 证书那些事

关于开发证书配置(Certificates & Identifiers & Provisioning Profiles),相信做iOS开发的同学没少被折腾.对于一个iOS开发小白.半吊子(比如像我自己)抑或老兵,或多或少会有或曾有过以下不详.疑问.疑惑甚至困惑: 什么是App ID?Explicit/Wildcard App ID有何区别?什么是App Group ID? 什么是证书(Certificate)?如何申请?有啥用? 什么是Key Pair(公钥/私钥)?有啥用?与证书有何关联

【转】 iOS Provisioning Profile(Certificate)与Code Signing详解

原文:http://blog.csdn.net/phunxm/article/details/42685597 引言 关于开发证书配置(Certificates & Identifiers & Provisioning Profiles),相信做iOS开发的同学没少被折腾.对于一个iOS开发小白.半吊子(比如像我自己)抑或老兵,或多或少会有或曾有过以下不详.疑问.疑惑甚至困惑: 什么是App ID?Explicit/Wildcard App ID有何区别?什么是App Group ID?