无论是爱还是恨,你都需要单例。实际上每个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];

    有些时候你希望有这种行为,但如果正在想要的是仅一个实例被实例化就需要注意这点。
 

利用dispatch_once创建单例的更多相关文章

  1. IOS:利用dispatch_once创建单例

    在之前有一篇学习笔记中,记载了一篇如何在OC中实现单例的文章:<IOS学习笔记4—Objective C—创建单例>自苹果引入了Grand Central Dispatch (GCD)(M ...

  2. IOS基础学习日志(七)利用dispatch_once创建单例及使用

    自苹果引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0)后,创建单例又有了新的方法,那就是使用dispatch_once函数,当然,随着演进的进行. ...

  3. iOS 转载一篇利用dispatch_once创建单例的文章

    感谢文章原作者,http://bj007.blog.51cto.com/1701577/649413

  4. 使用GCD的dispatch_once创建单例

    使用GCD的dispatch_once创建单例 介绍了创建单例的方式,不过后来发现其实在ios 4.0后有更加简单的方式. 就是使用GCD的功能 代码如下: + (instantClass *)sha ...

  5. [iOS dispatch_once创建单例]

    自苹果引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0)后,创建单例又有了新的方法,那就是使用dispatch_once函数,当然,随着演进的进行, ...

  6. ios oc 和 swfit 用dispatch_once 创建单例

    网上已经有方法了,我这里就是抄了下,原文链接 http://bj007.blog.51cto.com/1701577/649413 http://blog.csdn.net/u010124617/ar ...

  7. IOS 使用dispatch_once 创建单例

    + (instantClass *)sharedClient { static instantClass *_sharedClient = nil; static dispatch_once_t on ...

  8. iOS 创建单例的两种方法

    创建一个单例很多办法.我先列举一个苹果官方文档中的写法. [cpp] view plaincopy static AccountManager *DefaultManager = nil; + (Ac ...

  9. iOS:创建单例对象的两种方式

    单例模式:创建单例对象的两种方式 方式一:iOS4版本之前      static SingleClassManager *singleManager = nil;      +(SingleClas ...

随机推荐

  1. JSON学习总结

    最近几天使用json的需求比较急迫,所以学习了一下json.此文仅当笔记,以防忘却. 此文主要分为js和java总结: 先介绍json格式: JSON 数据的书写格式是:名称/值对. ***:可以更容 ...

  2. [转载] iptables配置实践

    原文: http://wsgzao.github.io/post/iptables/ iptables配置实践 By wsgzao 发表于 2015-07-24 文章目录 1. 前言 2. 更新历史 ...

  3. Can of Worms 【迭代/线段树】

    题意:一条直线上有n个炸弹,给出每个炸弹的爆炸半径,可以引爆另一个炸弹爆炸.问:每个炸弹爆炸后,最多有几个炸弹一起爆炸? 迭代,用线段树更新. #include <cstdio> #inc ...

  4. OpenERP QWeb模板标签笔记

    在OpenERP中,通过QWeb来对模板进行渲染后加载到浏览器中,而模板中有许多的标签来定制各种需求变化,在这里记录学习过程中碰到的标签定义,以方便查询. 模板中的标签统一都是以"t-&qu ...

  5. maven Connection refused: connect

    现象: 本地可以访问错误提示中的地址.但使用maven无法下载jar包. 环境: 浏览器上网需要使用代理 解决方法: 设置成正常代理可以.具体方法可以下载一个代理工具.只要IE配置成能直接访问http ...

  6. CSS3_概述、发展史、模块介绍、与浏览器之间的关系

    一.CSS3概述和CSS3的发展史: 1.css3概述: CSS3是CSS2的升级版本,3只是版本号,它在CSS2.1的基础上增加了很多强大的新功能.    目前主流浏览器chrome.safari. ...

  7. jackson annotations注解详解 (zhuan)

    http://blog.csdn.net/sdyy321/article/details/40298081 ************************************** 官方WIKI: ...

  8. python 图实现

    #coding:utf-8 __author__ = 'similarface' class Graph: def __init__(self,label,extra=None): #节点是类实例 s ...

  9. Django缓存优化之redis

    Redis 概述 Redis 是一个开源的Inmemory key-value 存储系统,性能高,很大程度上补偿了 memcached 的不足.支持多种存储类型,包括 string, list, se ...

  10. eclipse设置字体、背景(豆绿)色、自动提示

    背景色:(护眼豆绿色) window-->preferences-->General-->Editors-->Text Editors-->(最下遍一栏中的)Backgr ...