教你如何取消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(, ^{
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任务的更多相关文章
- iOS 多线程开发之OperationQueue(二)NSOperation VS GCD
原创Blog.转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...
- Swift之GCD 使用指南2
Grand Central Dispatch大中枢派发:joy: 或俗称 GCD 是一件极其强大的武器.它为你提供了很多底层工具(比如队列和信号量),你可以组合这些工具来实现自己想要的多线程效果.不幸 ...
- Eclipse取消汉化以及设置语言的方法
Eclipse取消汉化以及设置语言的方法 转 https://jingyan.baidu.com/article/11c17a2c2c1939f446e39d13.html Eclipse下载以后都是 ...
- ubuntu18.04下取消中键复制粘贴功能
Q: armlinux开发,主机采用ubuntu18.04操作系统,使用过程中关于鼠标中键有如下操作现象, 操作: 1.选中文本, 2.将鼠标光标定位到要插入的位置 3.按下鼠标中键 现象:将自动复制 ...
- dispatch_group_async 使用详解
dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作.这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了.下面是一段例子 ...
- ThinkPad E431按F1后直接进入系统无法进入BIOS
联想的ThinkPad系列笔记本一般是按F1进如BIOS的,但是由于现在联想的笔记本多数都是预装Win 8或者更高版本的系统,所以有时候就没办法直接按F1进去BIOS.其原因是因为Win 8或者更高版 ...
- iOS线程浅析
一.线程概述 1. iOS里面的线程按种类可分为同步线程和异步线程.同步线程指调用同步线程的地方必须等到同步线程运行完成才干够继续向下运行.而调用异步线程的地方则在运行完调用异步线程的语句后就能够继续 ...
- 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{ ...
- LOJ6686 Stupid GCD(数论,欧拉函数,杜教筛)
做题重心转移到 LOJ 了. 至于为什么,如果你知道“……”的密码,就去看吧. LOJ 上用户自创题大多数都不可做,今天看到个可做题(而且还是个水题),就来做了一发. 明显枚举立方根.(以下令 $m= ...
随机推荐
- Hibernate composite key
有两种方法来map composite key. 第一种用@IdClass第二种用@Embeddable,参考链接: http://stackoverflow.com/questions/358503 ...
- 浏览器如何生成URL
点击页面中的链接,浏览器会根据源码中相对URL路径作不同的处理: (1)有协议名称,但没有域名信息 对于这种形式的URL,它的协议,路径,查询字符串和片段ID都以它自身为准,但域名信息的部分,以引用它 ...
- 2017年PHP培训机构排名
2017年PHP培训机构排名 PHP培训属于IT培训的一个领域.随着互联网的火爆,PHP也变得异常火爆.通过对PHP培训机构的调查与了解,到底学员选择哪一家的PHP培训机构才能够学到真正的技术,PHP ...
- javaWeb学习总结(5)- HttpServletRequest应用
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的相关方法,即可以获得客户的这些信息 ...
- 二识angularJS
前言:记得三月份时下定决心说每天要更新一篇博客,学习点新东西,实践下来发现太不现实,生活中的事情很多,再喜欢也不能让它一件占据生活的全部吧,所以呢,以后顺其自然吧.之前有一篇'初识angular'因为 ...
- 小程序API录音后Silk格式转码MP3
问题 客户端使用小程序,需要录音功能然后到后台页面播放,由于微信提供的录音API压缩后的格式为 .silk格式的,但是这个格式其他播放器都是播放不了的,更何况html页面的audio标签更是不可能播放 ...
- PHP文件操作,多行句子的读取,file()函数,file_get_contents()函数,file_put_contents()函数,is_file,统计网站pv (访问量),文件的复制 copy,文件重命名 rename,删除文件 unlink
php中添加utf-8: header("Content-type:text/html;charset='UTF-8'"); 文件操作步骤: 1.在同一目录下建立一个file.tx ...
- 论文笔记 Network In Network
这篇论文思路简单.易实现.效果好,是一篇难得的佳作.从实现的角度理解,就是做了以下两个替换: 将线性卷积替换为多层感知机(某种程度上,线性卷积可以认为识一层感知机). 将全连接层用global ave ...
- selinux导致docker启动失败
1. 问题描述:一向运行正常的一群容器,突然有一天挂掉了,再也起不来,报错如下 Error response from daemon: devmapper: Error mounting '/dev/ ...
- Dojo初探之2:设置dojoConfig详解,dojoConfig参数详解+Dojo中预置自定义AMD模块的四种方式(基于dojo1.11.2)
Dojo中想要加载自定义的AMD模块,需要先设置好这个模块对应的路径,模块的路径就是这个模块的唯一标识符. 一.dojoConfig参数设置详解 var dojoConfig = { baseUrl: ...