全称是Grand Central Dispatch。可译为“牛逼的中枢调度器“
纯c语言,提供了非常强大的函数。
1.GCD是苹果公司为了多核的并行运算提出的解决方案。
2.GCD会自动的利用更多的cpu的核
3.GCD自动管理线程的生命周期(创建线程,调度任务,销毁线程)
4.程序员只需要告诉GCD想执行什么任务,并不需要编写任何线程的管理代码。
1.任务:执行什么操作
2.队列:用来存放任务
1.定制任务
确定想要做的事情
2.将任务添加到队列中
GCD自动将队列中的任务取出,放到对应的线程中执行。
任务的取出遵循队列的FIFO原则:先进先出,后进后出
1.用同步方式执行任务
dispatch_sync(dispatch_queue_t queue,dispatch_block_t block);
queue:队列
block:任务
2. 用异步方式执行任务
dispatch_async(dispatch_queue_t queue,dispatch_block_t block);
同步和异步的区别:
同步:在当前线程中执行。(不会开辟新线程)
异步:在另一条线程中执行。(开辟新线程)
异步只会开一个线程,所有的任务都会在这个新线程里面执行。
1.并发队列(Concurrent Dispatch Queue)
可以让多个任务同时执行,自动开启多个线程执行任务)
并发功能只有在异步(dispatch_async)的函数下才有效。
2.串行对垒
让任务一个接一个去执行
1.同步异步决定了要不要开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力。
异步:在新线程中执行任务,具备开启新线程的能力。
2.并发和串行决定了任务的执行方式
并发:多个任务同时执行
串行:一个任务执行结束后,才能执行下一个任务。
注意:同步任务的时候,使用并发队列不会创建多个子线程,会顺序执行任务。
开不开线程,由执行任务方法决定,同步不开线程,异步肯定开线程。
开多少线程由队列决定,串行最多开一个线程,并发可以开多个线程。具体开多少,有GCD底层决定,程序员不能控制。
特点:
(1)专门用来在主线程上调度任务的队列
(2)不会开启线程
(3)以先进先出的方式,在主线程空闲时才会调度队列中的任务在主线程中执行
(4)如果当前主线程有任务执行,那么无论主队列中被添加了什么任务,都不会被调度。
队列获取
-主队列是负责在主线程中调度任务的,会随着程序启动一起创建,主队列只需要获得不需要创建。
dispatch_queue_t queue = dispatch_get_main_queue();
会造成死锁
- (void)gcdDemo1 { dispatch_queue_t q = dispatch_get_main_queue(); NSLog(@"!!!!"); //同步 下面的代码必须执行了之后 才能继续执行后面的代码 但是主线程现在没空(没执行完gcdDemo1的代码 所以就会互相等待) dispatch_sync(q, ^{ NSLog(@"%@",[NSThread currentThread]); }); }
解决办法:
- (void)gcdDemo2{ NSLog(@"start"); // 获得主队列 dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 将任务同步添加到主队列中 dispatch_sync(queue, ^{ NSLog(@"%@",[NSThread currentThread]); }); }); NSLog(@"over"); }
GCD默认已经提供了全局的并发队列供整个应用使用,所以可以不用手动创建。
创建全局队列的函数为
dispatch_queue_t q = dispatch_get_global_queue(long identifier, unsigned long flags)
参数类型为:
(1)long identifier:ios 8.0 告诉队列执行任务的“服务质量 quality of service”,系统提供的参数有:
QOS_CLASS_USER_INTERACTIVE 0x21, 用户交互(希望尽快完成,用户对结果很期望,不要放太耗时操作) QOS_CLASS_USER_INITIATED 0x19, 用户期望(不要放太耗时操作) QOS_CLASS_DEFAULT 0x15, 默认(不是给程序员使用的,用来重置对列使用的) QOS_CLASS_UTILITY 0x11, 实用工具(耗时操作,可以使用这个选项) QOS_CLASS_BACKGROUND 0x09, 后台 QOS_CLASS_UNSPECIFIED 0x00, 未指定 iOS 7.0 之前 优先级 DISPATCH_QUEUE_PRIORITY_HIGH 2 高优先级 DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默认优先级 DISPATCH_QUEUE_PRIORITY_LOW (-2) 低优先级 DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台优先级
BACKGROUND表示用户不需要知道任务什么时候完成,如果选择这个选项速度慢得令人发指,非常不利于调试!对于优先级推荐不要搞得太负责,就用最简单,以免发生优先级反转。
(2)unsigned long flags:苹果官方文档是这样解释的: Flags that are reserved for future use。标记是为了未来使用保留的!所以这个参数应该永远指定为0
如果做ios8.0与ios7.0的适配,可以这样创建全局队列:
dispatch_queue_t q = dispatch_get_global_queue(0, 0);