教你如何取消GCD任務


      GCD 是一種非常方便的使用多線程的方式。通過使用 GCD,我們可以在確保盡量簡單的語法的前提下進行靈活的多線程編程。在 “復雜必死” 的多線程編程中,保持簡單就是避免錯誤的金科玉律。然而,GCD不像NSOperation那樣可以調用 -(void)cancel 取消一個操作的執行(注意這里的取消只是針對未執行的任務設置finished = YES,如果這個操作已經在執行了,那么我們只能等其操作完成。當我們調用cancel方法的時候,他只是將isCancelled設置為YES)。那我們想取消GCD任務怎么辦?難道真的束手無策了嗎?

     NO,怎么可能這么容易就放棄!下面我將為大家介紹如何實現取消GCD任務。

     第一種:dispatch_block_cancel

     iOS8之后可以調用dispatch_block_cancel來取消(需要注意必須用dispatch_block_create創建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);
}

     打印結果:

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也只能取消尚未執行的任務,對正在執行的任務不起作用。

  第二種:定義外部變量,用於標記block是否需要取消

      該方法是模擬NSOperation,在執行block前先檢查isCancelled = YES ?在block中及時的檢測標記變量,當發現需要取消時,終止后續操作(如直接返回return)。

- (void)gcdCancel{
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    __block BOOL isCancel = NO;
    
    dispatch_async(queue, ^{
        NSLog(@"任務001 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任務002 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任務003 %@",[NSThread currentThread]);
        isCancel = YES;
    });
    
    dispatch_async(queue, ^{
        // 模擬:線程等待3秒,確保任務003完成 isCancel=YES
        sleep(3);
        if(isCancel){
            NSLog(@"任務004已被取消 %@",[NSThread currentThread]);
        }else{
            NSLog(@"任務004 %@",[NSThread currentThread]);
        }
    });
}

     打印結果:

2017-07-08 15:33:54.017 beck.wang[3022:333990] 任務002 <NSThread: 0x60800007f740>{number = 4, name = (null)}
2017-07-08 15:33:54.017 beck.wang[3022:333989] 任務001 <NSThread: 0x600000261d80>{number = 3, name = (null)}
2017-07-08 15:33:54.017 beck.wang[3022:333992] 任務003 <NSThread: 0x618000261800>{number = 5, name = (null)}
2017-07-08 15:34:02.266 beck.wang[3022:334006] 任務004已被取消 <NSThread: 0x608000267100>{number = 6, name = (null)}

 

                                                              


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM