iOS 的单例模式 dispatch_once

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

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

或者我的理解是:

单例是一种类,该类只能实例化一个对象。

尽管这是单例的实际定义,但在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,布布扣,bubuko.com

时间: 07-12

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

iOS开发单例模式 dispatch_once

什么是单例 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案. iOS开发中如何使用单例 传统的单例构造方法 + (id)sharedInstance { static id sharedInstance; if(sharedInstance == nil){ sharedInstance

iOs开发 单例模式 省懒宏

#define singleton_h(name) + (instancetype)shared##name; #if __has_feature(obj_arc) #define singleton_m(name)static id _instance;+ (instancetype)shared##name{static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{_instance = [[self alloc] init];

iOS下单例模式实现(objective-c arc gcd)

单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这里主要介绍下在arc下,利用gcd实现单例. 第一步:声明一个静态实例 static SoundTool *_instance; 第二步:重写初始化方法 + (id)allocWithZone:(struct _NSZone *)zone 在对象初始化分配内存的时候都会调用这个方法,重写该方法时,即便用户没用通过shared方法获取实例,自己初始化依然可以保证得到的是同一个实例. 在gcd后,多线程下保证一个代码只被执

iOS中单例模式:MRC和ARC+GCD实现

iOS中单例模式的实现一般分为两种:MRC和ARC+GCD 1.MRC(非ARC) 非ARC的单例的实现方式: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <span style="font-family: 仿宋; font-size: 15px;">#import <Foundation/Foundation.h> @inter

iOS的单例模式(singleton)

自从设计模式出现以后,关于单例模式的争执就一直存在.我们很多时候需要一个全局的东西,保证全局仅有一份即可,这个时候单例是最佳的选择,但在多线程的环境下也需要做好线程保护. 在iOS下的UIApplication和NSFileManager就是很不错的例子--我们总有时候需要用到单例模式.不过写起代码来还是值得推敲一下: 最简单的例子如下,假设我们有一个testClass的类需要实现单例: + (id)sharedInstance { static testClass *sharedInstanc

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

注:本文所有权归作者所有,转载请注明出处 当希望在一个应用程序中某个类的对象只能存在一个的时候就可以考虑用单例模式来实现,单例模式在C++中比较容易实现(只需把构造函数声明为private),而在Objective-C中对象可以通过NSObject的alloc来产生,所以需要编写一些额外的代码来确保对象的唯一性,考虑到现在编写iOS APP代码几乎都是ARC方式,且GCD也已经被用烂了,故本文给出一种利用GCD技术来实现严格单例模式的ARC版本,具体代码如下所示,所有的注意点都写在了注释里面:

iOS-单例模式

何为单例模式,就是说如果在一个应用程序中,如果你想让一个类的实例使用的都是同一个,这时你就把该类设置为单例模式,iOS基础框架中有很多的单例模式类,如NSUserDefault,NSNotificationCenter等都是单例模式的设计. 单例模式的设计准则: 1.通过类方法获取单例实例, 2.必须是原子性的,保证多线程的访问安全 3.定义一个静态的指针变量,它会一直存在整个应用程序的生命周期中,一旦被初始化就会一直指向第一次创建的实例. 头文件: #import <Foundation/Fo

iOS 8:dispatch_once解惑

关键字:GCD  dispatch_once  单例  线程安全  double-check 以前在Java.C#等语言中,我们实现迟缓加载的单例模式一般写成如下形式(伪代码): private MyClass() {...} // 私有化构造方法 private static MyClass instance; // 承载对象的变量 pubic static MyClass getInstance() { // 完成实例化任务 if (instance == null) { // 第一次判断

ios设计模式——单例模式

一.定义 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 如何保证只能创建一个实例 二.使用 类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问 这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码 三.代码 方法一 1 #import "Singleton.h" 2 3 @implementation Singleton 4 5 static Singleton * shared = nil; 6 7 + (Singleton *)sha