一,Dispatch Queue

dispatch_async(queue, ^{
/*
*想执行的任务
*/ });

其中queue分为两种:

1,Serial Dispatch Queue 等待现在执行中处理结束。

2,Concurrent Dispatch Queue 不等待现在执行中处理结束。

二,dispatch_queue_create

用于生成queue.

1,生成Serial Dispatch Queue.

dispatch_queue_t mySerialDispatchQueue=dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);

2,生成Concurrent Dispatch Queue。

dispatch_queue_t myConcurrentDispatchQueue=dispatch_queue_create("com.example.gcd.MyConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);

3,用法

dispatch_queue_t myConcurrentDispatchQueue=dispatch_queue_create("com.example.gcd.MyConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(myConcurrentDispatchQueue, ^{
NSLog(@"block on myConcurrentDispatchQueue");
});

三,Main Dispatch Queue/Global Dispatch Queue

1,Main Dispatch Queue.

在主线程中执行的Dispatch Queue.

//Main Dispatch Queue的获取方法
dispatch_queue_t mainDisaptchQueue=dispatch_get_main_queue()
;

2,Global Dispatch Queue.

在所有应用程序中都能够使用的Dispatch Queue.它有4个优先级。

//Global Dispatch Queue的获取方法
//高优先级
dispatch_queue_t globalDispatchQueueHigh=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
//默认优先级
dispatch_queue_t globalDispatchQueueDefault=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//低优先级
dispatch_queue_t globalDispatchQueueLow=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
//后台优先级
dispatch_queue_t globalDispatchQueueBackground=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

3,用法

//在默认优先级的Global Dispatch Queue中执行block
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/*
*可并行执行的处理
*/
dispatch_async(dispatch_get_main_queue(), ^{
/*
*只能在主线程中执行的处理
*/ });
});

四,dispatch_set_target_queue

用于变更Dispatch Queue的生成。

//在后台执行动作处理的Serial Dispatch Queue的生成方法
dispatch_queue_t mySerialDispatchQueue=dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);
dispatch_queue_t globalDispatchQueueBackground=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_set_target_queue(mySerialDispatchQueue, globalDispatchQueueBackground);

五,dispatch_after

指定时间后执行处理。

1,ull是C语言的数值字面量,是显示表示类型时使用的字符串(表示“unsigned long long ”)。如果使用NSEC_PER_MSEC则可以以毫秒为单位计算。如果使用NSEC_PER_SEC则为毫微秒的数值。

2,dispatch_time_t计算相对时间。dispatch_walltime用于计算绝对时间。

在3秒后将指定的Block追加到Main Dispatch Queue.

dispatch_time_t time=dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC);
dispatch_after(time, dispatch_get_main_queue(), ^{
NSLog(@"waited at least three seconds.");
});

六,Dispatch Group

无论向什么样的Dispatch Queue中追加处理,使用Dispatch Group都可以监视这些处理执行的结束。一旦检测到所有执行结束,就可将结束的处理追加到Dispatch Queue中。这就是使用Dispatch Group的原因。

1,追加3个Block到Global Dispatch Queue,这些Block如果全部执行完毕,就会执行Main Dispatch Queue中结束处理用的Block.

 //追加3个Block到Global Dispatch Queue,这些Block如果全部执行完毕,就会执行Main Dispatch Queue中结束处理用的Block.
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"blk0");
});
dispatch_group_async(group, queue, ^{
NSLog(@"blk1");
});
dispatch_group_async(group, queue, ^{
NSLog(@"blk2");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"done");
});

2,在Dispatch Group中使用dispatch_group_wait函数等待全部处理执行结束。

 //在Dispatch Group中使用dispatch_group_wait函数等待全部处理执行结束。
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"blk0");
});
dispatch_group_async(group, queue, ^{
NSLog(@"blk1");
});
dispatch_group_async(group, queue, ^{
NSLog(@"blk2");
}); dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

七,dispatch_barrier_async

与Concurrent Dispatch Queue配合,dispatch)barrier_async函数可实现高效率的数据库访问和文件访问。

1,用法。

在blk_for_reading读操作后,加入写入处理。

 //blk3_for_reading后加入写入处理。
//dispatch_barrier_async会等待追加到Concurrent Dispatch Queue上的并行执行的处理全部结束之后,再将指定的处理追加到该Concurrent Dispatch Queue中。然后在由dispatch_barrier_async函数追加的处理执行完毕后,Concurrent Dispatch Queue才恢复为一般的动作。
dispatch_queue_t queue=dispatch_queue_create("com.example.gcd.ForBarrier", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, blk0_for_reading);
dispatch_async(queue, blk1_for_reading);
dispatch_async(queue, blk2_for_reading);
dispatch_async(queue, blk3_for_reading);
dispatch_barrier_async(queue, blk_for_writing);
dispatch_async(queue, blk4_for_reading);
dispatch_async(queue, blk5_for_reading);
dispatch_async(queue, blk6_for_reading);
dispatch_async(queue, blk7_for_reading);

八,dispatch_sync

“非同步”,容易形成死锁。

三种死锁的情况:

//dispatch_sync
//死锁1
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"Hello?");
}); //死锁2
dispatch_queue_t queue=dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);
dispatch_async(queue, ^{
dispatch_sync(queue, ^{
NSLog(@"Hello?");
});
}); //死锁3
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_async(queue, ^{
dispatch_sync(queue, ^{
NSLog(@"Hello?");
});
});

九,dispatch_apply.

dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API。该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等待全部处理执行结束。

用法:

dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(10, queue, ^(size_t index) {
NSLog(@"%ld",index);
});
NSLog(@"done");

十,dispatch_suspend/dispatch_resume.

挂起后,追加到Dispatch Queue中但尚未执行的处理在此之后停止执行。而恢复则使得这些处理能够继续执行。

用法:

 //将指定的Dispatch Queue挂起
dispatch_suspend(queue);
//将指定的Dispatch Queue恢复。
dispatch_resume(queue);

十一,Dispatch Semaphore.

Dispatch Semaphore是持有计数的信号,该计数是多线程编程中的计数类型信号。所谓信号,类似于过马路时常用的

手旗。而在Dispatch Semaphore中,使用计数来实现该功能。计数为0时等待,计数为1或大于1时,减去1而不等待。

1,用法:

    dispatch_time_t time=dispatch_time(DISPATCH_TIME_NOW, 1ull*NSEC_PER_SEC);
long result=dispatch_semaphore_wait(semaphore, time);
if (result==0) {
//计数为0时等待。
//可进行需要进行排他控制的处理
}else{
//计数为1或大于1时,减去1而不等待。
}

2,其好处。

原代码:

//此代码使用Global Dispatch Queue更新NSMutableArray类对象,所以执行后由内存错误导致应用程序异常结束的概率很高。此时应使用Dispatch Semaphore.
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSMutableArray *array=[[NSMutableArray alloc]init];
for (int i=0; i<10000; ++i) {
dispatch_async(queue, ^{
[array addObject:[NSNumber numberWithInt:i]];
});
}

修改后代码:

    //修改后代码
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//Dispatch Semaphore的计数初始值设定为“1”。保证可访问NSMutableArray类对象的线程,同时只能有1个
dispatch_semaphore_t semaphore=dispatch_semaphore_create(1); NSMutableArray *array=[[NSMutableArray alloc]init];
for (int i=0; i<10000; ++i) {
dispatch_async(queue, ^{
//一直等待,直到Dispatch Semaphore的计数值达到大于等于1.
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//Dispatch Semaphore的计数达到1后,开始减去1而不等待。此时,semaphore减去1变成0.
[array addObject:[NSNumber numberWithInt:i]];
//将semaphore的计数值加1.
dispatch_semaphore_signal(semaphore);
});
}

十二,dispatch_once。

保证在应用程序执行中只执行一次指定处理的API。

原代码:

//原代码
static int initialized=NO;
if (initialized==NO) {
//初始化
initialized=YES;
}

修改后代码:

 //修改后代码
static dispatch_once_t pred;
dispatch_once(&pred, ^{
//初始化
});

十三,Dispatch I/O。

在读取较大文件时,如果将文件分成合适的大小并使用Global Dispatch Queue并列读取的话,应该会比一般的读取

速度快不少。现在的输入/输出硬件已经可以做到一次使用多个线程更快地并列读取了。能实现这一功能的就是Dispatch I/O和Dispatch Data.

用法:

 //通过Dispatch I/O读写文件时,使用Global Dispatch Queue将1个文件按某个大小read/write.
dispatch_async(queue, ^{/*读取0~8191字节*/ });
dispatch_async(queue, ^{/*读取8192~16383字节*/ });
dispatch_async(queue, ^{/*读取16384~24575字节*/ });
dispatch_async(queue, ^{/*读取24576~32767字节*/ });
dispatch_async(queue, ^{/*读取32768~40959字节*/ });
dispatch_async(queue, ^{/*读取40960~49151字节*/ });
dispatch_async(queue, ^{/*读取49152~57343字节*/ });
dispatch_async(queue, ^{/*读取57344~65535字节*/ });

参考资料:《Objective-C高级编程 iOS与OS X多线程和内存管理》

【读书笔记】iOS-GCD-API的更多相关文章

  1. 《程序员的自我修养》读书笔记——系统调用、API

        系统调用 程序运行的时候,本身是没有权限访问多少系统资源的.系统资源有限,如果操作系统不进行控制,那么各个程序难免会产生冲突.线程操作系统都将可能产生冲突的系统资源保护起来,阻止程序直接访问. ...

  2. [读书笔记]iOS 7 UI设计 对比度

    好久没写随笔了,最近在读<iOS 7 byTutorials>,很不错,推荐给大家. 每一个好的程序员也都是一个设计师,不懂设计的程序员不是好的CTO.哈哈,开个小玩笑. iOS 7设计的 ...

  3. 读书笔记-iOS核心动画高级技巧

    如果不使用+imageNamed:,那么把整张图片绘制到CGContext可能是最佳的方式了. 这里我们利用了CALayer的KVC来存储和检索任意的值,将图层和索引打标签. 使用KVC打标签

  4. 《Java 8实战》读书笔记系列——第三部分:高效Java 8编程(四):使用新的日期时间API

    https://www.lilu.org.cn/https://www.lilu.org.cn/ 第十二章:新的日期时间API 在Java 8之前,我们常用的日期时间API是java.util.Dat ...

  5. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  6. 《More Effective C#》读书笔记

    <More Effective C#>这本书,大概是四年前看完的,但只整理了一部分读书笔记,后面有时间的话,会陆续补充的. More Effective C# :使用泛型 More Eff ...

  7. 第一章 Andorid系统移植与驱动开发概述 - 读书笔记

    Android驱动月考1 第一章 Andorid系统移植与驱动开发概述 - 读书笔记 1.Android系统的架构: (1)Linux内核,Android是基于Linux内核的操作系统,并且开源,所以 ...

  8. TJI读书笔记15-持有对象

    TJI读书笔记15-持有对象 总览 类型安全和泛型 Collection接口 添加元素 List 迭代器 LinkedList 栈 Set Map Queue Collection和Iterator ...

  9. WPF,Silverlight与XAML读书笔记第四十三 - 多媒体支持之文本与文档

    说明:本系列基本上是<WPF揭秘>的读书笔记.在结构安排与文章内容上参照<WPF揭秘>的编排,对内容进行了总结并加入一些个人理解. Glyphs对象(WPF,Silverlig ...

  10. 《深入理解bootstrap》读书笔记:第一章 入门准备

    一.bootstrap框架简介 Bootstrap是最流行的前端开发框架. 什么是框架:开发过程的半成品. bootstrap具有以下重要特性: (1)完整的CSS样式插件 (2)丰富的预定义样式表 ...

随机推荐

  1. storm分组模式

    Shuffle grouping: Tuples被随机分配到每一个bolt’s task,以便于每一个bolt’s task获得相同数量的tuples. Fields grouping: Stream ...

  2. 你或许不了解的C++函数调用(1)

    这篇博客名字起得可能太自大了,搞得自己像C++大牛一样,其实并非如此.C++有很多隐藏在语法之下的特性,使得用户可以在不是特别了解的情况下简单使用,这是非常好的一件事情.但是有时我们可能会突然间发现一 ...

  3. python面向对象编程(下)

    本篇详细介绍了Python 中类的成员.成员修饰符.类的特殊成员以及两个综合运用实例. 环境为:python3.5.1 类的成员 类的成员包括三大类:字段.方法和property属性 注:关于这三类成 ...

  4. EF错误记录

    纯属个人记录错误使用: 1.EntityType“area”未定义键.请为该 EntityType 定义键. 产生原因: 1.命名空间引用错误,可能命名重复导致引用错误 2.实体类无法识别主键或者未设 ...

  5. [Code] C#与js的正则表达式

    元字符: 单个字符: . [] 限定符: * + ? {n} {n,} {n,m} 头尾: ^ $' 其他: | () 正则表达式在js和C#中都有. C#中: 创建: var regex = new ...

  6. P6 EPPM Installation and Configuration Guide 16 R1 April 2016

    P6 EPPM Installation and Configuration Guide 16 R1         April 2016 Contents About Installing and ...

  7. weblogic 12C 数据源配置出错的解决办法

    驱动程序类名称:   11G 10.3.6与12G数据源配置有很大区别,整个一天才搞明白.   如有疑问可留言:http://www.cnblogs.com/endv/p/4110798.html 配 ...

  8. spring.net中的IOC和DI-初使用

    前面准备:下载spring.net并解压 下载地址:spring.net下载地址 Ioc:控制反转         DI:依赖注入 一.IOC(控制反转) 1.新建一个控制台程序springTest, ...

  9. 有关C#标签Attribute的熟悉

    Attribute 简单用法: 最近用到了,所以静下心来找些资料看了一下,终于把这东西搞清楚了. 一.什么是Attribute 先看下面的三段代码: 1.自定义Attribute类:VersionAt ...

  10. 《Node.js+MongoDB+AngularJS Web开发》读书笔记及联想

    总体介绍 <Node.js+MongoDB+AngularJS Web开发>,于2015年6月出版,是一本翻译过来的书,原书名为<Node.js,MongoDB and Angula ...