什么是GCD
全称是Grand Central Dispatch,中枢调度器
纯C语言,提供了非常多强大的函数
GCD 核心概念:将任务添加到队列,指定任务执行的方法
- 任务
-- 使用block 封装
-- block就是一个提前准备好的代码块,在需要的时候执行
- 队列 (负责任务的调度)
-- 串行:一个接一个的调度任务
-- 并发:可以同时调度多个任务
- 任务执行函数(任务都需要在线程中执行)
-- 同步执行:不会到线程池中获取子线程
-- 异步执行:只要有任务,就会到子线程获取子线程 (主队列除外)
队列决定任务未执行完时,是否会调用下个任务
同步异步决定是否会拿线程调度池里的线程
创建队列
dispatch_queue_create(constchar*_Nullablelabel,
dispatch_queue_attr_t _Nullable attr);
参数 1.队列的名称 C 语言字符串
2.队列的属性 DISPATCH_QUEUE_CONCURRENT 创建并发队列
DISPATCH_QUEUE_SERIAL 创建串行队列
第二个属性传NULL 默认是串行队列
dispatch_get_global_queue(longidentifier,unsignedlongflags);
获取全局队列 --- 并发队列
参数:
1. 涉及到系统适配
iOS 8 服务质量
QOS_CLASS_USER_INTERACTIVE 用户交互(希望线程快速被执行,不要用好使的操作)
QOS_CLASS_USER_INITIATED 用户需要的(同样不要使用耗时操作)
QOS_CLASS_DEFAULT 默认的(给系统来重置队列的)
QOS_CLASS_UTILITY 使用工具(用来做耗时操作)
QOS_CLASS_BACKGROUND 后台
QOS_CLASS_UNSPECIFIED 没有指定优先级
iOS 7 调度的优先级
- DISPATCH_QUEUE_PRIORITY_HIGH 2 高优先级
- DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默认优先级
- DISPATCH_QUEUE_PRIORITY_LOW (-2) 低优先级
- DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台优先级
提示:尤其不要选择BACKGROUND 不管是优先级还是服务质量,线程执行会慢到令人发指!!!
2.传0 是苹果为以后开发预留的占位
dispatch_get_main_queue(void)
主线程中执行的队列,不管都是同步还是异步 都是在主线程中执行!
修改队列优先级
dispatch_set_target_queue(dispatch_object_tobject,
dispatch_queue_t _Nullable queue);
指定要变更优先级的队列为第一个参数,指定要相同优先级的目标队列为第二个参数
注意:dispatch_get_main_queue 和 dispatch_get_global_queue 均不可作为第一个参数指定
同步执行方法,任务不执行完,就不会执行下一个任务,同步执行不会开启线程
- (void)gcdDemo
{
dispatch_queue_t t = dispatch_get_global_queue(0, 0);
void(^task)() = ^{
NSLog(@"%@",[NSThread currentThread]);
};
dispatch_sync(t, task);
}
异步执行任务 ,如果任务没有执行完毕,可以不用等待,异步执行下一个任务,具备开启线程的能力 异步通常又是多线程的代名词
- (void)gcdDemo
{
dispatch_queue_t t = dispatch_get_global_queue(0, 0);
void(^task)() = ^{
NSLog(@"%@",[NSThread currentThread]);
};
dispatch_async(t, task);
}
线程间通讯
- (void)gcdDemo
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"%@",[NSThread currentThread]);
//回到主线程
//这里用异步或者同步没区别,主队列只有一条主线程
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主线程%@",[NSThreadcurrentThread]);
});
});
}
串行队列 同步任务 不会开启线程,会顺序执行
- (void)gcdDemo
{
//1.队列 -- 串行
/** -- 参数
1.队列的名称 C 语言字符串
2.队列的属性
*/
dispatch_queue_t t = dispatch_queue_create("zhen", NULL);
for(inti =0; i <10; i ++) {
//同步执行任务
dispatch_sync(t, ^{
NSLog(@"%@ %d",[NSThreadcurrentThread],i);
});
}
}
串行队列 异步任务 会开启线程,顺序执行
- (void)gcdDemo
{
//串行队列
dispatch_queue_t t = dispatch_queue_create("zhen", NULL);
for(inti =0; i <10; i ++) {
//异步执行任务
NSLog(@"1213223232");
dispatch_async(t, ^{
NSLog(@"%@ %d",[NSThreadcurrentThread],i);
});
}
}
并发队列 异步任务 会开启线程 不会顺序执行
- (void)gcdDemo
{
dispatch_queue_t t = dispatch_queue_create("zhen", DISPATCH_QUEUE_CONCURRENT);
for(inti =0; i <10; i ++) {
dispatch_async(t, ^{
NSLog(@"%@ %d",[NSThreadcurrentThread],i);
});
}
}
并发队列 同步任务 不会开线程,顺序执行
- (void)gcdDemo7
{
dispatch_queue_t t = dispatch_queue_create("zhen", DISPATCH_QUEUE_CONCURRENT);
for(inti =0; i <10; i ++) {
dispatch_sync(t, ^{
NSLog(@"%@ %d",[NSThreadcurrentThread],i);
});
}
}
延时执行
- (void)gcdDemo
{
NSLog(@"hello");
/**
从现在开始,进过多少纳秒之后,让 queue队列,调度 block 任务,异步执行!
参数:
1.when
2.queue
3.block
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"等了1秒 %@",[NSThread currentThread]);
});
}
一次执行
- (void)gcdDemo
{
NSLog(@"hello");
//苹果提供的 一次之心机制,不仅能够保证一次执行!而且是线程安全的!!
//苹果推荐使用 gcd 一次执行,效率高
//不要使用互斥锁,效率低!
for(inti =0; i <10; i ++) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"能来几次%@",[NSThreadcurrentThread]);
});
}
}
经常用于写单例;开发中 有些界面需要请求多个接口,如果用户失效,多个接口则会返回多个失效,这里可以使用GCD一次执行来做
GCD调度 -- 多个任务执行完毕后通知群组
- (void)gcdDemo
{
//1.创建队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//2.调度组
dispatch_group_t group = dispatch_group_create();
//3.添加任务 异步执行 让队列调度任务执行的情况,最后通知群组
dispatch_group_async(group, queue, ^{
NSLog(@"任务1 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"任务2 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"任务3 %@",[NSThread currentThread]);
});
//通知群组,如果参数是主队列则在主线程执行
dispatch_group_notify(group, queue, ^{
NSLog(@"执行完毕 %@",[NSThreadcurrentThread]);
});
}
dispatch_barrier_async 栅栏函数,用于让任务按顺序执行
- (void)gcdDemo
{
dispatch_queue_t queue = dispatch_queue_create("name", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"1----- %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2----- %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3----- %@",[NSThread currentThread]);
});
//在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
//ps:这个queue不能是全局的并发队列
dispatch_barrier_async(queue, ^{
NSLog(@"这里来的顺序 %@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"4----- %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"5----- %@",[NSThread currentThread]);
});
}
dispatch_apply函数能进行快速迭代遍历 ,而且后边的代码会等待它执行完毕
- (void)gcdDemo
{
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index) {
// 执行10次代码,index顺序不确定
NSLog(@"%zu %@",index,[NSThreadcurrentThread]);
});
}
网友评论