控制任务执行的顺序
github地址
YSSimpleOperation
情景
- 任务A依赖于任务a,b,c的完成后才可以执行
常用方法是dispatch_group_t,或者轮询。
但是都感觉不够简洁和方便使用。
- 异步任务执行顺序控制
再异步任务a完成后,在其中内嵌任务b开始。
这样有时依赖内嵌比较深,不利于阅读维护。
方案
利用operationQueue和operation来管理任务的执行及依赖关系。
在自定义的operation的内将任务启动入口抛出,并控制operation的状态也交由外部控制。
原理
通过operationQueue管理operation来实现任务的执行时机的控制.
自定义Operation通过actionBlock抛出要在其中执行的任务,在任务完成后,一定要调用stopAction告诉operation状态变化(完成或取消),否则会导致该operation卡主operationQueue.
任务取消会调用cancelBlock,然后会调用finshBlock。被取消可能来自与operationQueue的取消或者stopAction的取消反馈。
finshBlock任务完成会被调用。
使用
- 依赖任务
NSMutableArray *list = [NSMutableArray array];
for (NSString *str in @[@"a", @"b"]) {
NSOperation *operation = [self createOperationWithSymbol:str queueType:YSQueue_Concurrent depentOperationList:nil];
[list addObject:operation];
}
for (NSString *str in @[@"A"]) {
[self createOperationWithSymbol:str queueType:YSQueue_Serial depentOperationList:[list copy]];
}
- (NSOperation *)createOperationWithSymbol:(NSString *)symbol queueType:(YSQueueType)queuType depentOperationList:(NSArray *)list {
NSOperation *operation = [self.manager addOperationInQueueType:queuType inQuality:NSQualityOfServiceDefault dependencyOperations:list actionBlock:^(YSStopActionBlock stopAction) {
/*
simulate task
*/
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"start loading -> %@...", symbol);
sleep(5);
NSLog(@"end loading -> %@...", symbol);
stopAction(false);
});
} cancelBlock:^{
NSLog(@"%@ cancel...", symbol);
} finshBlock:^{
NSLog(@"%@ finsh...", symbol);
}];
return operation;
}
- 串行任务
for (NSString *str in @[@"a", @"b"]) {
[self createOperationWithSymbol:str queueType:YSQueue_Serial depentOperationList:nil];
}
//like above
...
安装
- cocopods
pod 'YSSimpleOperation', '~>1.0.0'
- 源码
YSActionOperation.h
YSActionOperation.m
YSOperationManager.h
YSOperationManager.m
注意
不建议设置为单例,因为可能会有很多用户使用这个,在任务执行时一些不恰当的操作或达到最大并发数会致使你的任务阻塞或延后。
所以设置为全局的话请仔细检查。
网友评论