利用dispatch_once创建单例

原创 2013年12月01日 23:41:33
无论是爱还是恨,你都需要单例。实际上每个iOS或Mac OS应用都至少会有UIApplicationNSApplication.
什么是单例呢?Wikipedia是如此定义的:
在软件工程中,单例是一种用于实现单例的数学概念,即将类的实例化限制成仅一个对象的设计模式。
或者我的理解是:
单例是一种类,该类只能实例化一个对象。
    尽管这是单例的实际定义,但在Foundation框架中不一定是这样。比如NSFileMangerNSNotificationCenter,分别通过它们的类方法defaultManagerdefaultCenter获取。尽管不是严格意义的单例,这些类方法返回一个可以在应用的所有代码中访问到的类的共享实例。在本文中我们也会采用该方法。
    使用Objective-C实现单例模式的最佳方式向来有很多争论,开发者(包括Apple在内)似乎每几年就会改变他们的想法。当Apple引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0),他们也引入了一个很适合用于实现单例模式的函数。
    该函数就是dispatch_once
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);
    该函数接收一个dispatch_once用于检查该代码块是否已经被调度的谓词(是一个长整型,实际上作为BOOL使用)。它还接收一个希望在应用的生命周期内仅被调度一次的代码块,对于本例就用于shared实例的实例化。
dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
    Apple的GCD Documentation证实了这一点:
如果被多个线程调用,该函数会同步等等直至代码块完成。
    实际要如何使用这些呢?
    好吧,假设有一个AccountManager类,你想在整个应用中访问该类的共享实例。你可以按如下代码简单实现一个类方法:
+ (AccountManager *)sharedManager { 
    static AccountManager *sharedAccountManagerInstance = nil; 

    static dispatch_once_t predicate; dispatch_once(&predicate, ^{       
          sharedAccountManagerInstance = [[self alloc] init]; 
    });

    return sharedAccountManagerInstance; 

}
    这就意味着你任何时候访问共享实例,需要做的仅是:
AccountManager *accountManager = [AccountManager sharedManager];
    就这些,你现在在应用中就有一个共享的实例,该实例只会被创建一次。
    该方法有很多优势: 
           1 线程安全
           2 很好满足静态分析器要求
           3 和自动引用计数(ARC)兼容 
           4 仅需要少量代码
    该方法的劣势就是它仍然运行创建一个非共享的实例:
AccountManager *accountManager = [[AccountManager alloc] init];
    有些时候你希望有这种行为,但如果正在想要的是仅一个实例被实例化就需要注意这点。

转自:http://bj007.blog.51cto.com/1701577/649413

相关文章推荐

利用dispatch_once创建单例

无论是爱还是恨,你都需要单例。实际上每个iOS或Mac OS应用都至少会有UIApplication或NSApplication. 什么是单例呢?Wikipedia是如此定义的: 在软件工...

利用dispatch_once创建单例

无论是爱还是恨,你都需要单例。实际上每个iOS或Mac OS应用都至少会有UIApplication或NSApplication. 什么是单例呢?Wikipedia是如此定义的: 在软件工程中,单...
  • think12
  • think12
  • 2013年04月12日 16:51
  • 1638

利用dispatch_once创建单例

原文出处:http://bj007.blog.51cto.com/1701577/649413/     无论是爱还是恨,你都需要单例。实际上每个iOS或Mac OS应用都至少会有U...

IOS开发之dispatch_once创建单例

单例是一种类,该类只能在第一次用的时候实例化一个对象,后期直接调用此对象(有点共享的意思)。 在Foundation框架中比如NSFileManger和NSNotificationCenter,分别...

IOS 运用dispatch_once 创建单例 MARK

有些变量只需要初始化一次(如从文件中读取配置参数,读取设备型号等等),可以使用dispatch_once来进行读取优化,保证只调用API一次,以后就只要直接访问变量即可 范例如下: ...

iOS 创建单例的方法 dispatch_once

单例的运用场景是:一种类,该类只能实例化一个对象。 iOS 创建单例的方法有:dispatch_once 举例如下 假如有个全局的状态类,该类的接口部分如下: @interface Global...

IOS开发之dispatch_once创建单例

单例是一种类,该类只能在第一次用的时候实例化一个对象,后期直接调用此对象(有点共享的意思)。 在Foundation框架中比如NSFileManger和NSNotificationCenter,分别...

IOS_加速计_碰撞检测_小球位置修复_dispatch_once单例

H:/0802/01_accelerometer加速计+小球碰撞检测_ViewController.h// // ViewController.h // 加速计01-演练1 // // Crea...

GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例

(1)GCD实现的同步异步、串行并行。 ——同步sync应用场景:用户登录,利用阻塞 ——串行异步应用场景:下载等耗时间的任务 [objc] view plain...

滥用单例之dispatch_once死锁

现象 上周排查了一个bug,现象很简单,就是个Crash问题。但是读了一下crash Log以后,却发现堆栈报的错误信息却是第一次见到(吹牛的说,我在国内的iOS也能算第十二人了),包含以下还未...
  • fishmai
  • fishmai
  • 2016年07月27日 16:59
  • 1881
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用dispatch_once创建单例
举报原因:
原因补充:

(最多只允许输入30个字)