您的位置:首页 > 产品设计 > UI/UE

iOS多线程编程之Operation Queues

2016-07-13 11:08 489 查看
相对于GCD来说,Operation Queues会更加复杂一些,但是可以为operation之间添加依赖关系、暂停和恢复Operation Queue、取消正在执行的operation。这是GCD所做不到的。

Operation

要使用Operation Queue技术,需要使用
NSOperation
类来封装需要执行的任务。但是,
NSOperation
本身不能实例化,所以必须使用系统本身就实现好的两个子类:
NSInvocationOperation
NSBlockOperation
,或者自己创建一个
NSOperation
的子类。

NSInvocationOperation

使用
- (nullable instancetype)initWithTarget:(id)target selector:(SEL)sel object:(nullable id)arg;
创建一个
NSInvocationOperation
对象。这个对象可以随时更换
SEL
,例如:

operation.invocation.selector = @selector(operationMethod:);


NSBlockOperation

使用
+ (instancetype)blockOperationWithBlock:(void (^)(void))block;
创建一个
NSBlockOperation
对象。

自定义NSOperation

必须重写的方法:

1.
- (void)start
是一个operation的起点。

2.
- (BOOL)isConcurrent
是否是并发的,返回
YES


3.
- (BOOL)isExecuting
是否开始执行;

4.
- (BOOL)isFinished
是否执行完成;

其中第3、4个方法所代表的属性值发生变化时,我们需要手动触发
KVO
通知,以便外界能观察到这些值的变化。例如:

[self willChangeValueForKey:@"isFinished"];
_isFinished = YES;
[self didChangeValueForKey:@"isFinished"];


注意:为了支持operation的取消操作,在执行操作时要定期检查
isCancelled
的值,一旦返回
YES
则立刻停止之后的操作。当然也可以自己重写
- (void)cancel
方法来取消正在执行的操作,不过要记得调用
[super cancel]


CompletionBlock

使用
setCompletionBlock:
方法设置operation的
CompletionBlock


从字面意思上看很容易理解
CompletionBlock
的作用,但是值得一提的是,当一个operation调用了
cancel
方法取消后,也会执行
CompletionBlock
,所以需要在block中判断operation是否被取消。

添加依赖关系

使用
NSOperation
对象的两个方法:

- (void)addDependency:(NSOperation *)op;
- (void)removeDependency:(NSOperation *)op;


为operation添加依赖关系。例如:
[A addDependency:B]
表示A依赖于B,所以A需要等B执行完后才会开始执行。

注意:两个有依赖关系的operation不一定需要在同一个
OperationQueue
对象之中。

设置Operation在队列中的优先级

NSOperation
对象使用
setQueuePriority:
设置自身在
NSOperationQueue
对象中执行的优先级。参数有:

typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8
};


执行Operation

Operation对象有两种执行方式:

1. 直接让对象调用
- (void)start;
方法,但是这种方式并不能保证Operation对象是异步执行的;

2. 将Operation对象放入
NSOperationQueue
对象中,让
NSOperationQueue
的对象帮我们自动执行,OperationQueue会自动为这个 operation创建一个线程,不需要我们自己去实现异步执行。

取消Operation

使用
NSOperation
对象调用它的
cancel
方法取消这个 operation ,或者调用
NSOperationQueue
对象的
cancelAllOperations
方法取消这个OperationQueue 中所有的operation。

注意:一般情况下正在执行中的operation需要等到下一个检查
isCancelled
的位置才会停止,所以最好设置
CompletionBlock
来判断operation的
isCancelled
的值再决定是否执行operation完成后的操作。

例如:在一个根据用户实时输入的文字来进行搜索并展示返回结果的案例中,因为operation是并发的,假如用户先后输入了
A
B
C
,而返回的结果的顺序不一定是
A
AB
ABC
,所以最后展示的结果不一定是
ABC
的搜索结果,解决方法就是在用户输入文字后取消之前的operation,而在
CompletionBlock
中判断
isCancelled
的值,只有没被取消再使用主线程更新UI。

暂停和恢复OperationQueue

使用
NSOperationQueue
对象调用
setSuspended:
来实现暂停或恢复OperationQueue,不过正在执行的Operation并不能暂停,除非直接取消Operation。

想更深入的了解
Operation Queues
可以查看
AFNetworking
AFURLConnectionOperation
代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios 多线程