iOS 的单例模式 dispatch_once

有些变量仅仅须要初始化一次(如从文件里读取配置參数。读取设备型号等等),能够使用dispatch_once来进行读取优化。保证仅仅调用API一次,以后就仅仅要直接訪问变量就可以.

WeatherClient.h

#import "AFHTTPClient.h"



@interface WeatherClient : AFHTTPClient



+(WeatherClient *)sharedClient;



@end

WeatherClient.m

#import "WeatherClient.h"



@implementation WeatherClient



+(WeatherClient *)sharedClient

{

    static WeatherClient *sharedClient=nil;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken,^{sharedClient =[[WeatherClient alloc] initWithBaseURL:[NSURL URLWithString:API]];

    });

    return sharedClient;

}

@end

在软件project中,单例是一种用于实现单例的数学概念,即将类的实例化限制成仅一个对象的设计模式。
或者我的理解是:
单例是一种类。该类仅仅能实例化一个对象。

    虽然这是单例的实际定义,但在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 和自己主动引用计数(ARC)兼容 
           4 仅须要少量代码
    该方法的劣势就是它仍然执行创建一个非共享的实例:

AccountManager *accountManager = [[AccountManager alloc] init];

    有些时候你希望有这样的行为,但假设正在想要的是仅一个实例被实例化就须要注意这点。

 

iOS 的单例模式 dispatch_once的更多相关文章

  1. iOS开发单例模式 dispatch_once

    什么是单例 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源 ...

  2. iOS开发--单例模式

    单例模式在iOS开发中可能算是最常用的模式之一了,但是由于oc本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦,这里我就抛砖引玉来聊一聊iOS中单例模式的设计思路.关于单例模式更多的介绍请参考 ...

  3. QF——iOS的单例模式

    iOS的单例模式: 单例,即为单个实例,确保一个类里只有一个实例,向整个系统提供一个唯一的实例. 甚至为了严格提供唯一的实例,通常只允许该类自己提供实例化的方法,不允许出现其他入口.这时我们通常得重写 ...

  4. 【iOS】单例模式

    单例模式在软件开发中经常用到,在iOS系统framework也很多地方用到单例模式,例如 [NSUserDefaults standardUserDefaults], [NSBundle mainBu ...

  5. iOS设计模式-单例模式

    (一)什么是单例模式(Singleton) 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点 *最初的定义是在<设计模式>(Addison-Wesley)中 解读 1> ...

  6. Objective-C(iOS)严格单例模式正确实现

    注:本文所有权归作者所有,转载请注明出处 当希望在一个应用程序中某个类的对象只能存在一个的时候就可以考虑用单例模式来实现,单例模式在C++中比较容易实现(只需把构造函数声明为private),而在Ob ...

  7. ios之单例模式

    原帖地址:http://www.galloway.me.uk/tutorials/singleton-classes/ 本文为博主自行翻译,转载请注明出处:http://blog.csdn.net/i ...

  8. iOS开发-单例模式的解读

    现在网上的有很多人写单例模式,一个很基本的东西但是版本也有很多,新人看了难免有些眼花缭乱的感觉.自己最新比较闲,也过来写一些自己的心得. 在往下看之前,我们要明白一点,那就是在什么情况下我们才要用到单 ...

  9. iOS设计模式——单例模式

    单例模式用于当一个类只能有一个实例的时候, 通常情况下这个“单例”代表的是某一个物理设备比如打印机,或是某种不可以有多个实例同时存在的虚拟资源或是系统属性比如一个程序的某个引擎或是数据.用单例模式加以 ...

随机推荐

  1. vs2012 jsoncpp 链接错误

    解决: 项目->属性->C/C++->代码生成->运行库->设置与使用的.lib的版本一致.

  2. hashtable的用法

    C#中哈希表(HashTable)的用法详解 1.  哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器 ...

  3. 自学php【二】 PHP计算时间加一天

    最近几天在做一个项目,主要是将SQLserver数据到MySQL数据库,一个url跑一次 同步一次昨天的数据,由于很多数据需要同步,所以做了一个操作界面的,一个单纯跑url的 在其中涉及到了对于时间的 ...

  4. 最容易理解的HMM文章

    wiki上一个比较好的HMM例子 分类 隐马尔科夫模型 HMM(隐马尔科夫模型)是自然语言处理中的一个基本模型,用途比较广泛,如汉语分词.词性标注及语音识别等,在NLP中占有很重要的地位.网上关于HM ...

  5. js判断是安卓 还是 ios webview?

    通过判断浏览器的userAgent,用正则来判断是否是ios和Android客户端.代码如下: <script type="text/javascript"> var ...

  6. vue学习总结(简单介绍)

    声明式渲染 Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统: <div id="app"> {{ message }} < ...

  7. vue组件---动态组件之多标签页面

    首先看下效果图 代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...

  8. Vue.js 观察者(watch)

    Vue.js 观察者(watch) watch 属性用于监视 vue 实例上的数据变动,并相应的改变其他变量的值. 用法 实例 1 <!DOCTYPE html> <html> ...

  9. Linux学习笔记(二) 文件管理

    了解 Linux 系统基本的文件管理命令可以帮助我们更好的使用 Linux 系统,以下介绍几个常用的文件管理命令 1.pwd pwd 是 Print Working Directory 的简写,用于显 ...

  10. react-router v4 学习实践

    最近学习了 react-router v4,根据官方 API 文档和网上资源做了一个简单的路由示例. 先用官方的工具 create-react-app  初始化一个 react 项目模板,再根据自己的 ...