一. 函数执行任务
- GCD中有2个用来执行任务的常用函数
- 用同步的方式执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务
- 用异步的方式执行任务
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
- 同步和异步的区别
+ 同步:只能在当前线程中执行任务,不具备开启新线程的能力
+ 异步:可以在新的线程中执行任务,具备开启新线程的能力
- GCD中还有个用来执行任务的栅栏函数:
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
二. 并发队列
- 使用
dispatch_queue_create
函数创建并发队列
//const char * _Nullable label:队列名称(必须唯一:com.baidu.queue)
//dispatch_queue_attr_t _Nullable attr:队列的类型
dispatch_queue_t queue = dispatch_queue_create(<#const char * _Nullable label#>, <#dispatch_queue_attr_t _Nullable attr#>)
- GCD默认已经提供了全局的并发队列,供整个应用使用,可以无需手动创建
//<#long identifier#>:队列的优先级
//<#unsigned long flags#>:此参数未来使用,用0即可
dispatch_queue_t queue = dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>)
三. 串行队列
- GCD中获得串行有2种途径
- 使用
dispatch_queue_create
函数创建串行队列
- 使用
//const char * _Nullable label:队列名称(必须唯一:com.baidu.queue)
//dispatch_queue_attr_t _Nullable attr:队列类型传递NULL或者DISPATCH_QUEUE_SERIAL
dispatch_queue_t queue = dispatch_queue_create(<#const char * _Nullable label#>, <#dispatch_queue_attr_t _Nullable attr#>)
2. 使用主队列(跟主线程相关联的队列)
dispatch_queue_t queue = dispatch_get_main_queue()
+ 主队列是GCD自带的一种特殊的串行队列
+ 放在主队列中的任务,都会放到主线程中执行
四. 函数+队列
- 异步函数+并发队列:开启多条线程,并发执行任务
- 异步函数+串行队列:开启一条线程,串行执行任务
- 同步函数+并发队列:不开线程,串行执行任务
- 同步函数+串行队列:不开线程,串行执行任务
- 异步函数+主队列:不开线程,在主线程中串行执行任务
- 同步函数+主队列:不开线程,串行执行任务(注意死锁发生)
- 注意:同步函数和异步函数在执行顺序上面的差异
五. 使用Crearte
函数创建的并发队列
和全局并发队列
的主要区别
-
全局并发队列
在整个应用程序中本身是默认存在的并且对应有高优先级、默认优先级、低优先级和后台优先级一共四个并发队列,我们只是选择其中的一个直接拿来用。 - 而
Create
函数是实打实的从头开始去创建一个队列。 - 在iOS6.0之前,在GCD中凡是使用了带
Create
和retain
的函数在最后都需要做一次release
操作。而主队列和全局并发队列不需要我们手动release
。- 当然了,在
iOS6.0
之后GCD
已经被纳入到了ARC
的内存管理范畴中,即便是使用retain或者create函数创建的对象也不再需要开发人员手动释放,我们像对待普通OC
对象一样对待GCD
就OK。
- 当然了,在
- 在使用栅栏函数的时候,苹果官方明确规定栅栏函数只有在和使用
create
函数自己的创建的并发队列一起使用的时候才有效(没有给出具体原因)其它区别涉及到XNU
内核的系统级线程编程,不一一列举。 - 一些参考资料(自行研究):