今天看到一篇文章写到“当NSOperation被加入到NSOperationQueue之后,如果当前NSOperation已经被执行,并且还未执行完毕的时候,此时调用caccel,执行中的NSOperation会取消执行”,看到这觉得与自己的认知是有部分差异的,所以写一个demo验证下结果
/// 测试isExecuting中的operation是否能取消
- (void)multiThreadOperation{
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
operationQueue.maxConcurrentOperationCount = 1;
NSBlockOperation*beginBlockOperation = [NSBlockOperationblockOperationWithBlock:^{
[selfrunBegin];
}];
NSBlockOperation*lastBlockOperation = [NSBlockOperationblockOperationWithBlock:^{
[selfrunLast];
}];
[operationQueueaddOperation:beginBlockOperation];
[operationQueueaddOperation:lastBlockOperation];
NSLog(@"operationQueue.operationCount==%lu",(unsigned long)operationQueue.operationCount);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
NSLog(@"开始延时");
// [operationQueue cancelAllOperations];
for(NSOperation*opinoperationQueue.operations) {
NSLog(@"start op.isReady=%d, op.isExecuting=%d, op.isCancelled=%d, op.isFinished =%d", op.isReady, op.isExecuting, op.isCancelled, op.isFinished);
[opcancel];
NSLog(@"end op.isReady=%d, op.isExecuting=%d, op.isCancelled=%d, op.isFinished =%d", op.isReady, op.isExecuting, op.isCancelled, op.isFinished);
//
}
NSLog(@"结束延时");
});
}
- (void)runBegin{
NSLog(@"%s start",__func__);
sleep(5);
NSLog(@"%s end",__func__);
}
- (void)runLast{
NSLog(@"%s start",__func__);
NSLog(@"%s end",__func__);
}
代码如上,主要思路是,创建一个NSOperationQueue,将其maxConcurrentOperationCount=1,让其同一时间只能执行一个任务;
任何创建两个NSBlockOperation,在block中执行任务,其中一个任务耗时5s,一个任务直接只完成, 然后2s后将NSOperationQueue中的所有NSOperation进行cancel
执行结果如下:
operation执行结果通过打印结果可知,处于isExecuting中的NSOperation,在调用cancel的时候,还会继续执行完当前执行中的任务。出于isReady中的NSOperation会被cancel,而没有执行机会;
另外GCD也是同样的原理,但是GCD对block进行cancel,必须是通过dispatch_block_create创建的,然后通过dispatch_block_cancel进行cancel操作
// 测试gcd取消
- (void)gcdThreadOpeartion{
dispatch_queue_t queue = dispatch_queue_create("selfcreeatequeue", DISPATCH_QUEUE_CONCURRENT);
dispatch_block_t block1 = dispatch_block_create(0, ^{
NSLog(@"block 1 start thread=%@", [NSThread currentThread]);
sleep(5);
NSLog(@"block 1 end thread=%@", [NSThread currentThread]);
});
dispatch_block_t block2 = dispatch_block_create(0, ^{
NSLog(@"block 2 thread=%@", [NSThread currentThread]);
});
dispatch_block_t block3 = dispatch_block_create(0, ^{
NSLog(@"block 3 thread=%@", [NSThread currentThread]);
});
dispatch_async(queue, block1);
dispatch_async(queue, block2);
dispatch_async(queue, block3);
//dispatch_block_cancel来取消(需要注意必须用dispatch_block_create创建dispatch_block_t)
dispatch_block_cancel(block3);
//同样的,dispatch_block_cancel也只能取消尚未执行的任务,对正在执行的任务不起作用。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
dispatch_block_cancel(block1);
});
}
网友评论