- 什么是GCD
- GCD的优势
- GCD的使用2个步骤
/**
* 同步执行任务
*
* @param queue 任务要添加到那个队列
* @param block 要执行的任务
*/
void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
用异步的方式执行任务
/**
* 异步执行任务
*
* @param queue 任务要添加到那个队列
* @param block 要执行的任务
*/
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
同步和异步的执行
同步:在当前线程中执行
异步:在另一条线程中执行
队列的类型:串行队列、并发队列
并发队列 Concurrent Dispatch Queue
可以让多个任务并发执行(自动开启多个线程同时执行任务),并发队列只有在
异步函数(dispatch_async)下才有效。
串行队列 Serial dispatch Queue
让任务一个接一个的执行(一个任务执行完毕后再执行下一个队列)
同步和异步决定要不要开新的线程
同步 : 在当前线程中执行任务,不具备开线程的能力
异步 : 在新的线程中执行任务,具备开启线程的能力
并发和穿行决定了任务的执行方式
并发 : 多个任务并发执行
串行 : 一个任务执行完毕后再执行下一个任务
获取队列的方法
并发队列
GCD默认提供了全局的并发队列,供整个应用使用,不需要手动创建使用,获得并发
队列的函数:
/**
* 获取全局队列(并发队列)
*
* @param identifier 队列的优先级
* @param flags 保留使用,默认0
*
* @return 获取的全局队列
*/
dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);
获取串行队列有两种途径
/**
* 创建串行队列
*
* @param label 队列的名称
* @param attr 队列的属性,一般nil
*
* @return 创建的队列
*/
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
任务执行的四种方式分析
第一种 : 同步任务下使用串行队列
/**
* 同步任务 ------ 串行队列
*/
- (void)syncFuncSerialQueue {
// 创建队列
dispatch_queue_t tSerialQueue = dispatch_queue_create("serial queue synsc", NULL);
// 创建任务
dispatch_sync(tSerialQueue, ^{
NSLog(@"%@ tSerialQueue -- sync task1",[NSThread currentThread]);
});
dispatch_sync(tSerialQueue, ^{
NSLog(@"%@ tSerialQueue -- sync task2",[NSThread currentThread]);
});
dispatch_sync(tSerialQueue, ^{
NSLog(@"%@ tSerialQueue -- sync task3",[NSThread currentThread]);
});
// 结论 : 没有开新的线程,三个任务都在主线程执行
}
结果输出:没有开启新的线程,三个任务都在主线程下执行。
第二种 : 同步任务下使用并行队列
/**
* 同步任务 ------ 并行队列
*/
- (void)syncFuncMainQueue {
// 获取主队列
dispatch_queue_t tMainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建同步任务
dispatch_sync(tMainQueue, ^{
NSLog(@"%@ tMainQueue -- sync task1",[NSThread currentThread]);
});
dispatch_sync(tMainQueue, ^{
NSLog(@"%@ tMainQueue -- sync task2",[NSThread currentThread]);
});
dispatch_sync(tMainQueue, ^{
NSLog(@"%@ tMainQueue -- sync task3",[NSThread currentThread]);
});
// 结论 : 没有开新的线程,三个任务都在主线程执行
}
结果输出:没有开启新的线程,三个任务都在主线程下执行。
/**
* 同步任务 ------ 串行队列
*/
- (void)syncFuncSerialQueue {
// 创建队列
dispatch_queue_t tSerialQueue = dispatch_queue_create("serial queue synsc", NULL);
// 创建任务
dispatch_sync(tSerialQueue, ^{
NSLog(@"%@ tSerialQueue -- sync task1",[NSThread currentThread]);
});
dispatch_sync(tSerialQueue, ^{
NSLog(@"%@ tSerialQueue -- sync task2",[NSThread currentThread]);
});
dispatch_sync(tSerialQueue, ^{
NSLog(@"%@ tSerialQueue -- sync task3",[NSThread currentThread]);
});
// 结论 : 开启一条新的线程,但是三个任务都在一条线程执行
}
结果输出:开启一条新的线程,三个任务都在一条线程执行
第四种 : 异步任务下使用异步队列(1,1)
/**
* 异步任务 ------ 并行队列
*/
- (void)syncFunctMainQueue {
// 获取主队列
dispatch_queue_t tMainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建异步任务
dispatch_async(tMainQueue, ^{
NSLog(@"%@ tMainQueue -- async task1",[NSThread currentThread]);
});
dispatch_async(tMainQueue, ^{
NSLog(@"%@ tMainQueue -- async task2",[NSThread currentThread]);
});
dispatch_async(tMainQueue, ^{
NSLog(@"%@ tMainQueue -- async task3",[NSThread currentThread]);
});
// 结论 : 开启多条线程,三个任务都在不同的非主线程中执行
}
结果输出:
结论:
同步(sync)函数
- 并发队列 : 不会开线程
- 串行队列 : 不会开线程
异步(async)函数
- 并发队列 : 能开多条线程
- 串行队列 : 开启1条线程
注意
凡是函数名带有 creat/copy/new/retaion等字眼,都需要用release手动释放,GCD的数据类型在ARC的环境下不需要再做release,所以当遇见这些字
眼,先试着手动release。