- Grand Central Dispatch:纯C语言
- GCD为多核的并行而生
- GCD自动管理线程生命周期(创建,调度,销毁)
1.GCD的线程分配规则
2.四个重要概念
- 同步异步说的是函数的开启新线程的能力
- 同步:不具备开启新线程能力,只在当前线程中执行任务
- 异步:具备开启新线程的能力,可在多条线程中执行任务
- 并发串行说的是任务的执行顺序
- 串行:任务一个接一个的执行
- 并发:任务一起执行
3.使用语法:
- 并发队列
dispatch_queue_t queue = dispatch_queue_create("downloadA", DISPATCH_QUEUE_CONCURRENT);
- 串行队列
dispatch_queue_t queueA = dispatch_queue_create("downloadB", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queueB = dispatch_queue_create("downloadB", NULL);
- 全局并发队列
// 获取全局并发队列
dispatch_queue_t queueA = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queueB = dispatch_get_global_queue(0, 0);
- 主队列
//1.获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
- 异步函数
dispatch_async(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
- 同步函数
dispatch_sync(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
4.线程间通信
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
});
});
5.GCD常用函数
5.1.延迟执行
- 延迟执行的第一种方法:performSelector
[self performSelector:@selector(task) withObject:nil afterDelay:2.0];
- 2.延迟执行的第二种方法:NSTimer
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
- 3.延迟执行的第三种方法:GCD
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
/*
第一个参数:DISPATCH_TIME_NOW 从现在开始计算时间
第二个参数:延迟的时间 2.0 GCD时间单位:纳秒
第三个参数:队列
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
NSLog(@"GCD----%@",[NSThread currentThread]);
});
5.2.一次性代码
//不能放在懒加载中的,应用场景:单例模式
-(void)once
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"---once----");
});
}
5.3.栅栏函数:
- 栅栏函数不能使用全局并发队列,否则 dispatch_barrier_async 的作用会和 dispatch_async 的作用一样
// 创建并发队列
dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);
// 并发队列 + 异步函数任务1
dispatch_async(queue, ^{
for (NSInteger i = 0; i<100; i++) {
NSLog(@"download1-%zd-%@",i,[NSThread currentThread]);
}
});
// 并发队列 + 异步函数任务2
dispatch_async(queue, ^{
for (NSInteger i = 0; i<100; i++) {
NSLog(@"download2-%zd-%@",i,[NSThread currentThread]);
}
});
//并发队列 + 栅栏函数
dispatch_barrier_async(queue, ^{
NSLog(@"+++++++++++++++++++++++++++++");
});
// 并发队列 + 异步函数任务3
dispatch_async(queue, ^{
for (NSInteger i = 0; i<100; i++) {
NSLog(@"download3-%zd-%@",i,[NSThread currentThread]);
}
});
5.4.快速迭代
/*
迭代函数
第一个参数:遍历的次数
第二个参数:队列(并发队列)
第三个参数:index 索引
*/
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){
// 执行10次代码,index顺序不确定
});
6.队列组
-(void)group1
{
//1.创建队列
dispatch_queue_t queue =dispatch_get_global_queue(0, 0);
//2.创建队列组
dispatch_group_t group = dispatch_group_create();
//3.异步函数
/*
1)把任务添加到队列中
2)队列添加到队列组
3)监听任务的执行情况, 通知group
*/
dispatch_group_async(group, queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"2----%@",[NSThread currentThread]);
});
// 当队列组中所有的任务都执行完毕, 进入到下面的方法
dispatch_group_notify(group, queue, ^{
NSLog(@"-------dispatch_group_notify-------");
});
}
- 使用异步函数,在并发队列中可开启多条线程;在串行队列中只开启一条线程;在主队列中不能开启新线程。
- 注意:同步函数 + 主队列 = 死锁