iOS多线程编程之Operation Queues

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

Operation

要使用Operation Queue技术,需要使用NSOperation类来封装需要执行的任务。但是,NSOperation本身不能实例化,所以必须使用系统本身就实现好的两个子类:NSInvocationOperationNSBlockOperation,或者自己创建一个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是并发的,假如用户先后输入了ABC,而返回的结果的顺序不一定是AABABC,所以最后展示的结果不一定是ABC的搜索结果,解决方法就是在用户输入文字后取消之前的operation,而在CompletionBlock中判断isCancelled的值,只有没被取消再使用主线程更新UI。

暂停和恢复OperationQueue

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



想更深入的了解Operation Queues可以查看AFNetworkingAFURLConnectionOperation代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值