WIKI:Grand_Central_Dispatch
GCD是一种接近底层的基于线程池的多线程开发手段.遵循先进先出的规则.他会自动的管理线程的生命周期,而且会"智能"的利用到系统的多核.不过个人认为GCD最大的优势是闭包,以及不用对线程进行管理,写起来很简单有木有.
GCD中最重要的两个概念:
在GCD中,任务是我们多线程开发的基础.可以理解为NSThread中需要异步执行的代码.在GCD中表现为一个block.任务分类两种任务.同步任务和异步任务
任务类型 | 名字 | 说明 |
---|---|---|
sync | 同步任务 | 需要等待当队列中执行的任务执行完毕才能开始执行,并且不具备开启新线程的能力 |
async | 异步任务 | 无需等待当前队列中的任务执行完毕,并且具有新开启一个线程的能力 |
队列可以理解为任务的容器.队列分两种,串行队列和并行队列.可以将队列理解为一个工厂,任务即是货物,串行队列即工厂只有一条生产线,一个一个的生产.当一个任务做完了之后(单个产品从产品线生产完毕)才会进行下一个(同步任务和异步任务在里面的都是顺序执行).并行队列的话工厂有多条生产线,可以同时生产
队列类型 | 名字 | 说明 |
---|---|---|
DISPATCH_QUEUE_SERIAL | 串行队列 | 任务挨个进行.执行完了下一个,执行完了下一个,每次只执行一个任务 |
DISPATCH_QUEUE_CONCURRENT | 并行队列 | 每次执行多个任务 |
特殊的队列:
dispatch_get_main_queue()
来获取到主队列dispatch_get_global_queue(0, 0)
来获取到全局队列dispatch_get_global_queue(long identifier, unsigned long flags);
long identifier是队列优先级一般传入DISPATCH_QUEUE_PRIORITY_DEFAULT.flags参数目前没用.传0就行.
需要注意的是:并发队列的并发功能只能在并行任务async
中才有效果.串行队列中不能在同步任务中添加同步任务
// label: 队列名,一般用来调试用的
// attr:队列属性
dispatch_queue_create(<#const char * _Nullable label#>, <#dispatch_queue_attr_t _Nullable attr#>)
dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
/// queue:任务添加到的队列
/// block:执行的任务
dispatch_sync(<#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
dispatch_async(<#dispatch_queue_t _Nonnull queue#>, <#^(void)block#>)
同步任务会等待当前线程上任务执行完毕后才开始执行
dispatch_sync(dispatch_get_main_queue() ,^{
//执行的任务内容
});
注意,在串行队列的同步任务上添加同步任务会导致死锁
可以这样理解.现在有一个串行队列S.我们在上面添加了一个同步任务A.在A内我们想加一个同步任务B.因为串行队列,所以任务会一个接一个的往下运行.A要等B添加到S上才算运行完毕才算任务完成.而B要等A执行完毕才能进入队列…然后就.死锁了.
异步任务在串行队列上的表现形式和并行队列上并不一样
dispatch_async(dispatch_get_main_queue() ,^{
//执行的任务内容
NSLog(@"1");
});
dispatch_async(dispatch_get_main_queue() ,^{
//执行的任务内容
NSLog(@"2");
});
dispatch_async(dispatch_get_main_queue() ,^{
//执行的任务内容
NSLog(@"3");
});
dispatch_async(dispatch_get_main_queue() ,^{
//执行的任务内容
NSLog(@"4");
});
异步任务在串行队列上会按照任务添加的顺序逐步执行.打印将会是顺序的1.2.3.4.因为是在串行任务上