美文网首页OC学习
利用dispatch_once创建单例

利用dispatch_once创建单例

作者: 小神猫 | 来源:发表于2016-07-16 02:17 被阅读78次

利用dispatch_once创建单例

  • 无论是爱还是恨,你都需要单例。

  • 实际上每个iOS或Mac OS应用都至少会有UIApplication或NSApplication.

  • ** 什么是单例呢?Wikipedia是如此定义的:**

  • 在软件工程中,单例是一种用于实现单例的数学概念,即将类的实例化限制成仅一个对象的设计模式。

  • 或者我的理解是:单例是一种类,该类只能实例化一个对象。

  • 尽管这是单例的实际定义,但在Foundation框架中不一定是这样。比如NSFileManger和NSNotificationCenter,分别通过它们的类方法defaultManager和defaultCenter获取。尽管不是严格意义的单例,这些类方法返回一个可以在应用的所有代码中访问到的类的共享实例。
  • 使用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 仅需要少量代码
    该方法的劣势就是它仍然运行创建一个非共享的实例:
AccountManager *accountManager = [[AccountManager alloc] init];
    有些时候你希望有这种行为,但如果正在想要的是仅一个实例被实例化就需要注意这点。

相关文章

  • 利用dispatch_once创建单例

    利用dispatch_once创建单例 无论是爱还是恨,你都需要单例。 实际上每个iOS或Mac OS应用都至少会...

  • Effective Objective-C读后笔记(4)

    31、dispatch_once实现单例 使用dispatch_once实现单例设计模式。 32、多用枚举器,少用...

  • iOS 单例中dispatch_once的原理

    先来段代码: 这是利用dispatch_once实现单例的方式,运行看看会输出什么: 生成完单例对象后,在其他地方...

  • dispatch_once创建单例

    写蓝牙的时候,需要使用到单例,于是参照网上的例子,使用写了这样的一个单例,权当记录: dispatch_once被...

  • ios 单例

    单例写法 dispatch_once 上文是 dispatch_once的代码,可以看出通过predicate判断...

  • swift两种方式实现单例

    在swift中有两种方法可以实现单例模式。 一、使用dispatch_once ,代码如下: 二、利用let只能赋...

  • 单例

    使用GCD快速创建dispatch_once 1, 单例在外界容易被篡改: 在.h中添加提示语 +(instanc...

  • iOS-多线程(三)-GCD函数

    单次函数dispatch_once 单次函数一般用来创建单例或者是执行只需要执行一次的程序。 dispatch_o...

  • 学习笔记 - 两行代码创建单例

    利用两行代码创建单例

  • 2018-03-09

    2018-03-21 45. 单例dispatch_once的使用 说明:dispatch_once 是线程安全的...

网友评论

  • DeepChad:这样单例写法不完整,如果确定想使对象唯一,+ (id)allocWithZone和- (id)copyWithZone也要写,少用单例

本文标题:利用dispatch_once创建单例

本文链接:https://www.haomeiwen.com/subject/opxujttx.html