1. 简介
NSOperation,NSOperationQueue是基于GCD更高一层的封装,是苹果提供的一套针对多线程的解决方案。
NSOperation,NSOperationQueue的优点
- 可以添加代码块在操作完成后执行
- 添加操作依赖关系,方便控制操作的执行顺序
- 设置操作的优先级
- 很方便的取消一个操作的执行
- 使用KVO观察操作执行状态的更改(isFinished,isExecuting,isCancelled)
2.使用步骤
NSOperation需要配合NSOperationQueue来实现多线程。因为默认情况下NSOperation单独使用系统同步执行操作,配合使用NSOperationQueue能够更好的实现异步执行操作。
- 创建操作(将一个操作封装到NSOperation对象中)
- 创建队列 (创建NSOperationQueue对象)
- 将操作添加到队列中,并开始执行
3. 基本使用
NSoperation是一个抽象类,我们不能直接使用,需要使用它的子类来封装操作,这里有三种方式可以封装操作:
- 使用NSInvocationOperation
- 使用NSBlockOperation
- 自定义继承自NSoperation的子类
3.1 NSInvocationOperation的使用
打印结果:
在其他线程执行
3.2 NSBlockOperation的使用
NSBlockOperation提高addExecutionBlock增加额外操作的方法。这些操作可以在不同的线程中同时(并发)执行,只有当所有的操作执行完成才视为完成。 如果添加的操作很多的话,blockOperationWithBlock的操作也可能会在其他线程中(非当前线程)执行,这里是由系统决定的。可以使用addExecutionBlock多添加些操作:
3.3 自定义继承自NSoperation的子类的使用
NSoperation的子类不能满足需要,我们可以通过自定义子类实现,通过重新main方法或者start方法来定义自己的operation对象,重写main方法比较简单。我们不需要管理操作的属性状态isFinished和isExecuting,当main执行完之后,操作也就执行完了。
4. NSOperationQueue的使用
NSOperationQueue包含两种队列:主队列和自定义队列。自定义队列同时包含了串行和并发功能。 主队列: NSOperationQueue *queue = [NSOperationQueue mainQueue];
自定义队列: NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSOperationQueue控制串行和并发
通过控制最大操作并发数maxConcurrentOperationCount实行串行和并发
- 默认为-1,表示不进行控制,可以并发执行
- 为1时,队列为串行队列,只能串行执行
- 大于1时,队列为并发队列,并发执行,这个值不能超过系统限制,即使设置的无穷大系统会取设置值和默认最大值的小值。
NSOperation操作依赖
NSOperation可以通过操作依赖,控制操作的执行顺序。
添加依赖 - (void)addDependency:(NSOperation *)op;
移除依赖 - (void)removeDependency:(NSOperation *)op;
@property (readonly, copy) NSArray<NSOperation *> *dependencies;
添加依赖:
NSOperation优先级
@property NSOperationQueuePriority queuePriority;
NSOperation、NSOperationQueue 非线程安全可以通过加锁和解锁实现线程安全
注意:无论是操作或者是队列的暂停和取消都不是立即将当前的操作取消,而是等当前操作完成之后,不在往下执行。 暂停和取消的区别在于暂停的操作可以恢复,继续往下执行,取消的操作是不能恢复的,不能继续往下执行。