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. jQuery实现文字横向滚动效果

    HTML代码: <div id="aaa" style="width:100px; position:relative; white-space:nowrap; o ...

  2. Android基础TOP6_2:Gallery +Image完成画廊

    Activity: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmln ...

  3. RabbitMQ调用

    添加 gradle依赖complie("com.rabbitmq:amqp-client:5.0.0") Hello, World Working Queues Publish/S ...

  4. Jenkins系列之Jenkins的安装(一)

    自动化测试的时候通常我们都会进行持续集成,下面是持续集成工具Jenkins的安装 Jenkins优点: 开源免费 跨平台,支持所有的平台 web形式的可视化的管理页面 安装配置超级简单 tips及时快 ...

  5. C# 创建与读写配置文件

    配置文件内容为 <?xml version="1.0" encoding="utf-8" ?> <configuration> < ...

  6. CAD与用户交互在图面上选择一个实体(com接口VB语言)

    主要用到函数说明: IMxDrawUtility::GetEntity 与用户交互到在图面上选择一个实体,详细说明如下: 参数 说明 [out] IMxDrawPoint** pPickPoint 返 ...

  7. thinkphp 5.0 “No input file specified”问题

    最近在用thinkphp5.0,想要试一下强制路由模式,却发现一直报错, 在网上一通乱找,最后发现是因为不能正确识别path_info造成的, 解决方案就是在 public目录下修改 ".h ...

  8. Vue.js 计算属性(computed)

    Vue.js 计算属性(computed) 如果在模板中使用一些复杂的表达式,会让模板显得过于繁重,且后期难以维护.对此,vue.js 提供了计算属性(computed),你可以把这些复杂的表达式写到 ...

  9. 【2018百度之星初赛(A)】1002 度度熊学队列

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6375 Knowledge Point: STL - map:https://www.cnblogs.c ...

  10. Kattis - missinggnomesD Missing Gnomes (思路题)

    题目: 题意: 给出已经去除了几个数的一个序列,任务是将去除的数字插回去补全这个序列,输出字典序排在第一的那个补全的序列. 例如: 样例输入: 5 3 1 4 2 样例输出: 1 3 4 2 5 思路 ...