zoukankan      html  css  js  c++  java
  • 教你如何取消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)}

                                                                  

  • 相关阅读:
    CentOS7-Docker容器入门
    CentOS7-Docker 配置国内镜像源
    CentOS7 下 yum 安装 Docker CE
    VirtualBox 配置 CentOS7网卡信息
    MySQL忘记密码后重置密码(Mac )
    三栏布局的n种实现
    Seata Server环境搭建
    Nacos安装
    排查系统端口被占用
    Netty网络高性能核心原理
  • 原文地址:https://www.cnblogs.com/beckwang0912/p/7136862.html
Copyright © 2011-2022 走看看