CGD是线程管理,不如说是队列管理,那么我们先来介绍一下GCD中常用的队列:
Serial Diapatch Queue 串行队列
当任务相互依赖,具有明显的先后顺序的时候,使用串行队列是一个不错的选择 创建一个串行队列:
dispatch_queue_t serialDiapatchQueue=dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_SERIAL);
第一个参数为队列名,第二个参数为队列类型,当然,第二个参数人如果写NULL,创建出来的也是一个串行队列。然后我们在异步线程来执行这个队列:
dispatch_async(serialDiapatchQueue, ^{
NSLog(@"1");
});
dispatch_async(serialDiapatchQueue, ^{
sleep(2);
NSLog(@"2");
});
dispatch_async(serialDiapatchQueue, ^{
sleep(1);
NSLog(@"3");
});
为了能更好的理解,我给每个异步线程都添加了一个log,看一下日志平台的log:
2016-03-07 10:17:13.907 GCD[2195:61497] 1
2016-03-07 10:17:15.911 GCD[2195:61497] 2
2016-03-07 10:17:16.912 GCD[2195:61497] 3
没错,他在61497这个编号的线程中做了串行输出,相互彼此依赖,串行执行
Concurrent Diapatch Queue 并发队列
与串行队列刚好相反,他不会存在任务间的相互依赖。 创建一个并发队列:
dispatch_queue_t concurrentDiapatchQueue=dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
比较2个队列的创建,我们发现只有第二个参数从DISPATCH_QUEUE_SERIAL变成了对应的DISPATCH_QUEUE_CONCURRENT,其他完全一样。
用同一段代码,换一种队列我们来比较一下效果:
dispatch_async(concurrentDiapatchQueue, ^{
NSLog(@"1");
});
dispatch_async(concurrentDiapatchQueue, ^{
sleep(2);
NSLog(@"2");
});
dispatch_async(concurrentDiapatchQueue, ^{
sleep(1);
NSLog(@"3");
});
输出的log:
2016-03-07 10:42:38.289 GCD[2260:72557] 1
2016-03-07 10:42:39.291 GCD[2260:72559] 3
2016-03-07 10:42:40.293 GCD[2260:72556] 2
我们发现,log的输出在3个不同编号的线程中进行,而且相互不依赖,不阻塞。
Global Queue & Main Queue
这是系统为我们准备的2个队列:
Global Queue其实就是系统创建的Concurrent Diapatch Queue
Main Queue 其实就是系统创建的位于主线程的Serial Diapatch Queue
通常情况我们会把这2个队列放在一起使用,也是我们最常用的开异步线程-执行异步任务-回主线程的一种方式:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"异步线程");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"异步主线程");
});
});
*通过上面的代码我们发现了2个有意思的点:
dispatch_get_global_queue存在优先级,没错,他一共有4个优先级:*
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSLog(@"4");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSLog(@"3");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"1");
});
在指定优先级之后,同一个队列会按照这个优先级执行,打印的顺序为1、2、3、4,当然这不是串行队列,所以不存在绝对回调先后。
异步主线程 在日常工作中,除了在其他线程返回主线程的时候需要用这个方法,还有一些时候我们在主线程中直接调用异步主线程,这是利用dispatch_async的特性:block中的任务会放在主线程本次runloop之后返回。这样,有些存在先后顺序的问题就可以得到解决了。