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(, ^{
sleep();
NSLog(@"block1 %@",[NSThread currentThread]);
}); dispatch_block_t block2 = dispatch_block_create(, ^{
NSLog(@"block2 %@",[NSThread currentThread]);
}); dispatch_block_t block3 = dispatch_block_create(, ^{
NSLog(@"block3 %@",[NSThread currentThread]);
}); dispatch_async(queue, block1);
dispatch_async(queue, block2);
dispatch_block_cancel(block3);
}

打印结果:

-- ::39.935 beck.wang[:] block2 <NSThread: 0x6180000758c0>{number = , name = (null)}
-- ::44.940 beck.wang[:] block1 <NSThread: 0x618000074f80>{number = , 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, );

    __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();
if(isCancel){
NSLog(@"任务004已被取消 %@",[NSThread currentThread]);
}else{
NSLog(@"任务004 %@",[NSThread currentThread]);
}
});
}

打印结果:

-- ::54.017 beck.wang[:] 任务002 <NSThread: 0x60800007f740>{number = , name = (null)}
-- ::54.017 beck.wang[:] 任务001 <NSThread: 0x600000261d80>{number = , name = (null)}
-- ::54.017 beck.wang[:] 任务003 <NSThread: 0x618000261800>{number = , name = (null)}
-- ::02.266 beck.wang[:] 任务004已被取消 <NSThread: 0x608000267100>{number = , name = (null)}

教你如何取消GCD任务的更多相关文章

  1. iOS 多线程开发之OperationQueue(二)NSOperation VS GCD

    原创Blog.转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...

  2. Swift之GCD 使用指南2

    Grand Central Dispatch大中枢派发:joy: 或俗称 GCD 是一件极其强大的武器.它为你提供了很多底层工具(比如队列和信号量),你可以组合这些工具来实现自己想要的多线程效果.不幸 ...

  3. Eclipse取消汉化以及设置语言的方法

    Eclipse取消汉化以及设置语言的方法 转 https://jingyan.baidu.com/article/11c17a2c2c1939f446e39d13.html Eclipse下载以后都是 ...

  4. ubuntu18.04下取消中键复制粘贴功能

    Q: armlinux开发,主机采用ubuntu18.04操作系统,使用过程中关于鼠标中键有如下操作现象, 操作: 1.选中文本, 2.将鼠标光标定位到要插入的位置 3.按下鼠标中键 现象:将自动复制 ...

  5. dispatch_group_async 使用详解

    dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作.这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了.下面是一段例子 ...

  6. ThinkPad E431按F1后直接进入系统无法进入BIOS

    联想的ThinkPad系列笔记本一般是按F1进如BIOS的,但是由于现在联想的笔记本多数都是预装Win 8或者更高版本的系统,所以有时候就没办法直接按F1进去BIOS.其原因是因为Win 8或者更高版 ...

  7. iOS线程浅析

    一.线程概述 1. iOS里面的线程按种类可分为同步线程和异步线程.同步线程指调用同步线程的地方必须等到同步线程运行完成才干够继续向下运行.而调用异步线程的地方则在运行完调用异步线程的语句后就能够继续 ...

  8. LOJ 6229 LCM / GCD (杜教筛+Moebius)

    链接: https://loj.ac/problem/6229 题意: \[F(n)=\sum_{i=1}^n\sum_{j=1}^i\frac{\mathrm{lcm}(i,j)}{\mathrm{ ...

  9. LOJ6686 Stupid GCD(数论,欧拉函数,杜教筛)

    做题重心转移到 LOJ 了. 至于为什么,如果你知道“……”的密码,就去看吧. LOJ 上用户自创题大多数都不可做,今天看到个可做题(而且还是个水题),就来做了一发. 明显枚举立方根.(以下令 $m= ...

随机推荐

  1. 高效工作的秘诀——Doit.im使用总结报告

    从上次购买doit.im pro账户到现在已经快一年了,从摸索到现在的熟悉,目前这款软件已经成为我工作生活中最为重要的效率工具,在此之前也用过很多软件进行时间管理,综合起来评价,doit应该算是最棒的 ...

  2. Java读取ini配置

    本文转载地址:       http://www.cnblogs.com/Jermaine/archive/2010/10/24/1859673.html 不够通用,呵呵. 读取ini的配置的格式如下 ...

  3. repo版本切换

    repo init -u https://android.googlesource.com/platform/manifest repo sync 之后 这样初始化之后,相当于下载了全部的分支, 本想 ...

  4. 《安卓网络编程》之第六篇 Android中的WIFI和蓝牙

    关于WIFI就不多介绍啦,直接来个段子吧. 问:“WiFi对人体有伤害么?” 答:“不清楚,反正没有WiFi我就浑身不舒服. 比较重要的一点就是WifiManager  wm=(WifiManager ...

  5. cocoapods安装和使用常见问题及解决方案

    cocopods安装后pod install出现以下错误 /usr/local/Cellar/ruby/2.4.1_1/lib/ruby/2.4.0/rubygems.rb:270:in find_s ...

  6. 树莓派控制GPIO(Python)

    如果你的raspi没有安装python那么先   sudo apt-get update sudo apt-get install python-dev   例如想要控制35管脚的亮灭: 先建一个文本 ...

  7. Redis 小白指南(二)- 基础命令和五大类型:字符串、散列、列表、集合和有序集合

    Redis 小白指南(二)- 基础命令和五大类型:字符串.散列.列表.集合和有序集合 引言 目录 基础命令 字符串类型 散列类型 列表类型 集合类型 有序集合类型 基础命令 1.获得符合规则的键名列表 ...

  8. vmware和centOS的安装

    如果勾上了,会立即在本机开辟20g的空间,需要很长时间 选择电脑中ISO镜像的位置,之后点击开启虚拟机! 这个密码是root用户的密码!管理员密码! 可以选择我们的Minimal没有界面的!

  9. iOS CAShapeLayer、CADisplayLink 实现波浪动画效果

    iOS CAShapeLayer.CADisplayLink 实现波浪动画效果 效果图 代码已上传 GitHub:https://github.com/Silence-GitHub/CoreAnima ...

  10. 渗透测试工具Nmap从初级到高级

    Nmap是一款网络扫描和主机检测的非常有用的工具. Nmap是不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器.它可以适用于winodws,linux,mac等操作系统.Nmap ...