GCD介绍
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法
基于C语言,提供了非常多强大的函数术语
同步 (Synchronous)
在当前线程中执行任务,不具备开启新线程的能力
提交的任务在执行完成后才会返回
同步函数: dispatch_sync()异步 (Asynchronous)
在新线程中执行任务,具备开启新线程的能力
提交的任务立刻返回,在后台队列中执行
异步函数: dispatch_async()串行 (Serial)
一个任务执行完毕后,再执行下一个任务
并发 (Concurrent)
多个任务同时执行(自动开启多个线程),
只有在异步函数下才有效
描述 | 说明 |
---|---|
queue | 队列 |
main | 主队列 |
global | 全局队列 |
dispatch_queue_t | 描述队列 |
dispatch_block_t | 描述任务 |
dispatch_once_t | 描述一次性 |
dispatch_time_t | 描述时间 |
dispatch_group_t | 描述队列组 |
dispatch_semaphore_t | 描述信号量 |
函数 | 说明 |
---|---|
dispatch_sync() | 同步执行 |
dispatch_async() | 异步执行 |
dispatch_after() | 延时执行 |
dispatch_once() | 一次性执行 |
dispatch_apply() | 提交队列 |
dispatch_queue_create() | 创建队列 |
dispatch_group_create() | 创建队列组 |
dispatch_group_async() | 提交任务到队列组 |
dispatch_group_enter() / dispatch_group_leave() | 将队列组中的任务未执行完毕的任务数目加减1(两个函数要配合使用) |
dispatch_group_notify() | 监听队列组执行完毕 |
dispatch_group_wait() | 设置等待时间(返回 0成功,1失败) |
注意:
1.所有的执行都放到队列中(queue),队列的特点是FIFO(先提交的先执行)
2.必须在主线程访问 UIKit 的类
3.并发队列只在异步函数下才有效
#基本使用
1 | NSLog(@"当前线程: %@", [NSThread currentThread]); |
延时执行 dispatch_after()
dispatch_after()延迟一段时间把一项任务提交到队列中执行,返回之后就不能取消
常用来在在主队列上延迟执行一项任务
1 | NSLog(@"当前线程 %@", [NSThread currentThread]); |
一次性执行 dispatch_once()
整个程序运行中,只会执行一次 (默认线程是安全的)
dispatch_once() 以线程安全的方式执行且仅执行其代码块一次
1 | for (NSInteger i = 0; i < 10; i++) { |
1 | //使用GCD初始化单例 |
提交 dispatch_apply()
把一项任务提交到队列中多次执行,具体是并行执行还是串行执行由队列本身决定
dispatch_apply不会立刻返回,在执行完毕后才会返回,是同步的调用。
队列
任务1,任务2依次执行,所有任务都执行成功后回到主线程
(效率不高)
1 | NSLog(@"当前线程 %@", [NSThread currentThread]); |
队列组
任务1,任务2同时执行,所有任务都执行成功后回到主线程
(效率高)
1 | NSLog(@"当前线程 %@", [NSThread currentThread]); |
#串行与并发
串行队列
一个任务执行完毕后,再执行下一个任务
主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行
1 | //(1)使用dispatch_queue_create函数创建串行队列 |
并发队列
多个任务并发执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效!!!
GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建
并发队列优先级 | 快捷值 | 优先级 |
---|---|---|
DISPATCH_QUEUE_PRIORITY_HIGH | 2 | 高 |
DISPATCH_QUEUE_PRIORITY_DEFAULT | 0 | 中(默认) |
DISPATCH_QUEUE_PRIORITY_LOW | (-2) | 低 |
DISPATCH_QUEUE_PRIORITY_BACKGROUND | INT16_MIN | 后台 |
1 | //(1)使用dispatch_get_global_queue函数获得全局的并发队列 |
异步函数_并发队列
(开启新线程,并发执行任务)
1 | NSLog(@"当前线程 %@", [NSThread currentThread]); |
异步函数_串行队列
(开启新线程,串行执行任务)
1 | NSLog(@"当前线程 %@", [NSThread currentThread]); |
同步函数_并发队列
(不会开启新线程,并发执行任务失效!)
1 | NSLog(@"当前线程 %@", [NSThread currentThread]); |
同步函数_串行队列
(不会开启新线程,串行执行任务)
1 | NSLog(@"当前线程 %@", [NSThread currentThread]); |