教你如何取消GCD任务
GCD 是一種非常方便的使用多線程的方式。通過使用 GCD,我們可以在確保盡量簡單的語法的前提下進(jìn)行靈活的多線程編程。在 “復(fù)雜必死” 的多線程編程中,保持簡單就是避免錯(cuò)誤的金科玉律。然而,GCD不像NSOperation那樣可以調(diào)用 -(void)cancel 取消一個(gè)操作的執(zhí)行(注意這里的取消只是針對(duì)未執(zhí)行的任務(wù)設(shè)置finished = YES,如果這個(gè)操作已經(jīng)在執(zhí)行了,那么我們只能等其操作完成。當(dāng)我們調(diào)用cancel方法的時(shí)候,他只是將isCancelled設(shè)置為YES)。那我們想取消GCD任務(wù)怎么辦?難道真的束手無策了嗎?
NO,怎么可能這么容易就放棄!下面我將為大家介紹如何實(shí)現(xiàn)取消GCD任務(wù)。
第一種:dispatch_block_cancel
iOS8之后可以調(diào)用dispatch_block_cancel來取消(需要注意必須用dispatch_block_create創(chuàng)建dispatch_block_t)
代碼示例:
- (void)gcdBlockCancel{
dispatch_queue_t queue = dispatch_queue_create("com.gcdtest.www", DISPATCH_QUEUE_CONCURRENT);
dispatch_block_t block1 = dispatch_block_create(0, ^{
sleep(5);
NSLog(@"block1 %@",[NSThread currentThread]);
});
dispatch_block_t block2 = dispatch_block_create(0, ^{
NSLog(@"block2 %@",[NSThread currentThread]);
});
dispatch_block_t block3 = dispatch_block_create(0, ^{
NSLog(@"block3 %@",[NSThread currentThread]);
});
dispatch_async(queue, block1);
dispatch_async(queue, block2);
dispatch_block_cancel(block3);
}
打印結(jié)果:
2017-07-08 13:59:39.935 beck.wang[2796:284866] block2 <NSThread: 0x6180000758c0>{number = 3, name = (null)}
2017-07-08 13:59:44.940 beck.wang[2796:284889] block1 <NSThread: 0x618000074f80>{number = 4, name = (null)}
同樣的,dispatch_block_cancel也只能取消尚未執(zhí)行的任務(wù),對(duì)正在執(zhí)行的任務(wù)不起作用。
第二種:定義外部變量,用于標(biāo)記block是否需要取消
該方法是模擬NSOperation,在執(zhí)行block前先檢查isCancelled = YES ?在block中及時(shí)的檢測(cè)標(biāo)記變量,當(dāng)發(fā)現(xiàn)需要取消時(shí),終止后續(xù)操作(如直接返回return)。
- (void)gcdCancel{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block BOOL isCancel = NO;
dispatch_async(queue, ^{
NSLog(@"任務(wù)001 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)002 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)003 %@",[NSThread currentThread]);
isCancel = YES;
});
dispatch_async(queue, ^{
// 模擬:線程等待3秒,確保任務(wù)003完成 isCancel=Y(jié)ES
sleep(3);
if(isCancel){
NSLog(@"任務(wù)004已被取消 %@",[NSThread currentThread]);
}else{
NSLog(@"任務(wù)004 %@",[NSThread currentThread]);
}
});
}
打印結(jié)果:
2017-07-08 15:33:54.017 beck.wang[3022:333990] 任務(wù)002 <NSThread: 0x60800007f740>{number = 4, name = (null)}
2017-07-08 15:33:54.017 beck.wang[3022:333989] 任務(wù)001 <NSThread: 0x600000261d80>{number = 3, name = (null)}
2017-07-08 15:33:54.017 beck.wang[3022:333992] 任務(wù)003 <NSThread: 0x618000261800>{number = 5, name = (null)}
2017-07-08 15:34:02.266 beck.wang[3022:334006] 任務(wù)004已被取消 <NSThread: 0x608000267100>{number = 6, name = (null)}
總結(jié)
以上是生活随笔為你收集整理的教你如何取消GCD任务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业中squid+iptables多模块
- 下一篇: 农民思考互联网时代农民的未来