多线程
1 | 异步函数+主队列 不会开线程,串行执行 |
一、容易混淆的俗语
有四个术语比较容易混淆:同步
、异步
、并发
、串行
.
- 同步和异步主要影响有:能不能开启新线程
- 同步: 只能在当前线程中执行任务, 不具备开启新线程的能力
- 异步: 可以在新的线程中执行任务, 具备开启新线程的能力
- 并发金和串行的只要影响: 任务的执行方式
- 并发: 允许多个任务并发(同事执行)
- 串行: 一个任务执行完毕后,在执行下一个任务
二、执行任务
1、GCD中有2个用来执行任务的常用函数
用同步的方式执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
• queue 队列
• block 任务
用异步的方式执行任务
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
2、GCD中还有个用来执行任务的函数:
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
在前面的任务执行结束后它才执行,而且它后面的任务执行完成后才会执行
注意:这个queue
不能是全局的并发列队
三、列队的类型
1、并发列队
可以让并发任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async
) 函数下才有效
使用 dispatch_queue_create
函数创建队列
dispatch_queue_t
dispatch_queue_create(const char *label, //队列名称
dispatch_queue_attr_t attr); //队列的类型
dispatch_queue_t queue = dispatch_queue_create("re.yuxiang", DISPATCH_QUEUE_CONCURRENT); // 创建并发队列
GCD默认已经提供了全局的并发队列,供整个应用使用, 可以无需受用创建
使用dispatch_get_global_queue
函数获得全局的并发队列
dispatch_queue_t dispatch_get_global_queue(
dispatch_queue_priority_t priority, //队列的优先级
long flags); //此参数暂时无用 用0即可
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //获得全局并发队列
- 全局并发队列的优先级
1
2
3
4#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 //默认(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台
2、串行列队
让任务一个接着一个执行(一个任务执行完毕后,在执行下一个任务)
GCD中获得串行有2种途径
使用dispatch_queue_creat
函数创建串行队列
dispatch_queue_creat queue = dispatch_queue_creat("yuxiang.ren", NULL); // 队列类型传递NULL或者DISPATCH_QUEUE_SERIAL
3、主队列(跟主线程相关联的队列)
主队列是GCD自带的一种特殊的串行队列
放在主队列中的任务, 都会返回主线程中执行
使用dispatch_get_main_queue()
获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
四、NSOperation
- 相关概念
NSOperation是对GCD的包装
两个核心概念[队列+操作] - 基本使用
NSOperation
本身是抽象类,只能只有他的子类三个子类分别是:`NSBlockOperation`,`NSInvocationOperation`,以及自定义继承自`NSOperation`的类
NSOperation
和NSOperationQueue
结合使用实现多线程开发NSoperationQueue
NSOperation
中的两种队列
- 主队列: 通过mainQueue获得,凡是放到主队列中的人物都将在主线程中完成
- 非主队列: 直接[alloc init]出来的队列, 非主队列同时具备了并发和串行的功能, 通过设置最大并发数属性来控制任务是并发执行还是串行执行
五、GCD和NSOperation的对比
- GCD和NSOperation的区别
GCD
是纯C语言的API,而操作队列
则是OC对象- 在GCD中,任务用快(
block
)来表示, 而块是轻量级的数据结构;相反操作队列中的[操作]NSOperation
则是个更加重量级的OC对象 - 具体该使用
GCD
还是使用NSOperation
需要看具体情况
NSOperation
和NSoperationQueue
相对GCD
的好处
NSOperationQueue
可以方便的调用cancel
方法来取消某个操作, 而GCD中的任务是无法取消的NSOperation
可以方便的制定操作间的依赖关系NSOperation
可以通KVO提供对NSOperation
对象的精细控制(比如监听当前的操作是否取消)NSOperation
可以方便的制定操作的优先级,操作优先级表示此操作与队列中其他操作间的优先关系- 通过自定义
NSOperation
的子类可以实现操作重用
六、单例
- 基本概念
- 单利模式
在程序运行过程中,一个类只有一个实例 - 使用场合
在整个应用程序中,功效一份资源(这份资源只需要创建初始化一次)
- ARC实现单利
- 在类的内部提供一个
static
修饰的全局变量 - 提供一个类方法, 方便外接访问
- 重写
+allocWithZone
方法,保证永远只为单例对象分配一次内存空间 - 严谨写法, 重写
-CopyWithZone
方法和-MutableCopyWithZone
方法
- 在类的内部提供一个