多线程
GCD
• 全称是Grand Central Dispatch
• 纯C语言,提供了非常多强大的函数
执行任务的方式
同步的方式
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务
异步的方式
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
队列类型
可以分为两大类
1.并发队列 • Concurrent Dispatch Queue
• 可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
• 并发功能只有在异步(dispatch_async)函数下才有效
2.串行队列 • Serial Dispatch Queue
• 让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
总结
• 同步和异步决定了要不要开启新的线程
• 同步:在当前线程中执行任务,不具备开启新线程的能力
• 异步:在新的线程中执行任务,具备开启新线程的能力
• 并发和串行决定了任务的执行方式
• 并发:多个任务并发(同时)执行
• 串行:一个任务执行完毕后,再执行下一个任务
全局队列
本质就是并发队列
dispatch_get_global_queue(0,0);
全局队列和并发队列的区别
• 并发队列有名称,可以跟踪错误,全局队列没有
• 在ARC中不需要考虑释放内存, dispatch_release(q);不允许调用。在MRC中需要手动释放内存,
并发队列是create创建出来的 在MRC中见到create就要release,全局队列不需要release(只有一个)
• 一般我们使用全局队列
主队列
主队列,异步任务
• 不开线程,同步执行
• 主队列特点:如果主线程正在执行代码暂时不调度任务,等主线程执行结束后在执行任务
• 主队列又叫 全局串行队列
主队列,同步任务
• 程序执行不出来(死锁)
• 死锁的原因,当程序执行到下面这段代码的时候
• 主队列:如果主线程正在执行代码,就不调度任务
• 同步执行:如果第一个任务没有执行,就继续等待第一个任务执行完成,再执行下一个任务此时互相等待,程序无法往下执行(死锁)
dispatch_sync(q, ^{
NSLog(@"%@ -- %d",[NSThread currentThread],i);
});
死锁解决方案
• (主队列,同步执行)放入异步执行 解决死锁
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"全局队列,异步执行 %@",[NSThread currentThread]);
//此时这行代码 在子线程中运行,同步执行不用等待主线程执行此同步执行的任务
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"主队列,同步执行 %@",[NSThread currentThread]);
});
NSLog(@"==");
});
Snip20160605_3.png
GCD其他操作
延时操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
• dispatch_after的定义
dispatch_after(dispatch_time_t when,
dispatch_queue_t queue,
dispatch_block_t block);
• dispatch_after的参数
参数1 dispatch_time_t when
多少纳秒之后执行
参数2 dispatch_queue_t queue
任务添加到那个队列
参数3 dispatch_block_t block
要执行的任务
Arc下的单例实现
static id _instancetype
+(instancetype)shardName{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instancetype = [[self alloc]init]
});
return _instancetype;
}
调度组
• 有时候需要在多个异步任务都执行完成之后继续做某些事情,
比如下载歌曲,等所有的歌曲都下载完毕之后 转到 主线程提示用户
//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]);
});
//4 所有任务都执行完成后,获得通知 (异步执行)
//等调度组中队列的任务完成后,把block添加到指定的队列
// dispatch_group_notify(group, queue, ^{
// NSLog(@"okkkkkkk %@",[NSThread currentThread]);
// });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//更新UI控件,提示用户
NSLog(@"okkkkkkk %@",[NSThread currentThread]);
});
NSLog(@"over");
[TOC]
网友评论