dispatch_once的实现分析

dispatch_once可以保证代码被执行一次

+(NSDateFormatter*)getDBDateFormat
{
    static NSDateFormatter* format;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        format = [[LKDateFormatter alloc]init];
        format.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    });
    return format;
}

dispatch_once_t的描述是typedef long dispatch_once_t;

Description A predicate for use with the dispatch_once function.

dispatch_once展开是

void
_dispatch_once(dispatch_once_t *predicate, dispatch_block_t block)
{
    if (DISPATCH_EXPECT(*predicate, ~0l) != ~0l) {
        dispatch_once(predicate, block);
    }
}

~0l 是 long 的0 取反也就是 一大堆1

我们再展开DISPATCH_EXPECT, 是__builtin_expect((x), (v))

__builtin_expect是GCC(version>=2.9)引进的宏,其作用就是帮助编译器判断条件跳转的预期值,避免跳转造成时间乱费。并没有改变其对真值的判断。

所以呢dispatch_once可以看成

+(NSDateFormatter*)getDBDateFormat
{
    static NSDateFormatter* format;
    static long onceToken = 0;
    if (onceToken != 0){
        1...
        {
            format = [[LKDateFormatter alloc]init];
            format.dateFormat = @"yyyy-MM-dd HH:mm:ss";
        }
        2...
    }
    return format;
}

我们可以猜测在下面的2...里的代码是修改了 onceToken的值

下断点查看一下,发现在1里改变了一次

然后在2里改成了-1

这样我们就不难理解dispatch_once的逻辑了

时间: 2024-08-03 04:55:50

dispatch_once的实现分析的相关文章

dispatch_once的实现分析(转)

dispatch_once可以保证代码被执行一次 +(NSDateFormatter*)getDBDateFormat { static NSDateFormatter* format; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ format = [[LKDateFormatter alloc]init]; format.dateFormat = @"yyyy-MM-dd HH:mm:ss";

dispatch_once认识分析

dispatch_once为了确保代码运行一次 +(NSDateFormatter*)getDBDateFormat { static NSDateFormatter* format; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ format = [[LKDateFormatter alloc]init]; format.dateFormat = @"yyyy-MM-dd HH:mm:ss"; }

RACSignal 冷信号和热信号底层实现分析

前言 由于最近在写关于RACSignal底层实现分析的文章,当然也逃不了关于冷热信号操作的分析.这篇文章打算分析分析如何从冷信号转成热信号的底层实现. 目录 1.关于冷信号和热信号的概念 2.RACSignal热信号 3.RACSignal冷信号 4.冷信号是如何转换成热信号的 一. 关于冷信号和热信号的概念 冷热信号的概念是源自于源于.NET框架Reactive Extensions(RX)中的Hot Observable和Cold Observable, Hot Observable是主动的

RunLOOP浅分析

RunLoop 是 iOS 和 OS X 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理.之后会介绍一下在 iOS 中,苹果是如何利用 RunLoop 实现自动释放池.延迟回调.触摸事件.屏幕刷新等功能的. 目录 RunLoop 的概念 RunLoop 与线程的关系 RunLoop 对外的接口 RunLoop 的 Mode RunLoop 的内部逻辑 RunLoop 的底层实现 苹果用 RunLoop 实现的功能 Autore

爱奇艺、优酷、腾讯视频竞品分析报告2016(一)

1 背景 1.1 行业背景 1.1.1 移动端网民规模过半,使用时长份额超PC端 2016年1月22日,中国互联网络信息中心 (CNNIC)发布第37次<中国互联网络发展状况统计报告>,报告显示,网民的上网设备正在向手机端集中,手机成为拉动网民规模增长的主要因素.截至2015年12月,我国手机网民规模达6.20亿,有90.1%的网民通过手机上网. 图 1  2013Q1~2015Q3在线视频移动端和PC端有效使用时长份额对比 根据艾瑞网民行为监测系统iUserTracker及mUserTrac

Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)

原文:http://www.cnblogs.com/heshan664754022/archive/2013/03/27/2984357.html Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量) 用文本编辑工具打开用于启动Tomcat的批处理文件startup.bat,仔细阅读.在这个文件中,首先判断CATALINA_HOME环境变量是否为空,如果为空,就将当前目录设为CATALINA_HOME的值.接着判断当前目录下是否存在bin\catalina.bat,如果文件

C# 最佳工具集合: IDE 、分析、自动化工具等

C#是企业中广泛使用的编程语言,特别是那些依赖微软的程序语言.如果您使用C#构建应用程序,则最有可能使用Visual Studio,并且已经寻找了一些扩展来对您的开发进行管理.但是,这个工具列表可能会改变您编写C#代码的方式. C#编程的最佳工具有以下几类: IDE VS扩展 编译器.编辑器和序列化 反编译和代码转换工具 构建自动化和合并工具 版本控制 测试工具和VS扩展 性能分析 APM 部署自动化 容器 使用上面的链接直接跳转到特定工具,或继续阅读以浏览完整列表.

秒杀系统架构分析与实战

0 系列目录 秒杀系统架构 秒杀系统架构分析与实战 1 秒杀业务分析 正常电子商务流程 (1)查询商品:(2)创建订单:(3)扣减库存:(4)更新订单:(5)付款:(6)卖家发货 秒杀业务的特性 (1)低廉价格:(2)大幅推广:(3)瞬时售空:(4)一般是定时上架:(5)时间短.瞬时并发量高: 2 秒杀技术挑战 假设某网站秒杀活动只推出一件商品,预计会吸引1万人参加活动,也就说最大并发请求数是10000,秒杀系统需要面对的技术挑战有: 对现有网站业务造成冲击 秒杀活动只是网站营销的一个附加活动,

Openfire分析之二:主干程序分析

引言 宇宙大爆炸,于是开始了万物生衍,从一个连人渣都还没有的时代,一步步进化到如今的花花世界. 然而沧海桑田,一百多亿年过去了-. 好复杂,但程序就简单多了,main()函数运行,敲个回车,一行Hello World就出来了,所以没事多敲敲回车,可以练手感-. 一.程序入口 Java的程序入口是main方法,Openfire也不例外.可以全局检索一下"void main",可以看到,Openfire的main函数有两个: (1)org.jivesoftware.openfire.lau