GCD学习 —— 三
学习学习dispatch_block,在向队列中添加任务时,可以直接在对应的函数中添加 block。但是如果想对任务进行操作,比如监听任务、取消任务,就需要获取对应的 block。
1 创建Block
第一种方式如下:
1
dispatch_block_t dispatch_block_create(dispatch_block_flags_t flags, dispatch_block_t block);
在该函数中,
flags参数用来设置block的标记,block参数用来设置具体的任务。flags的类型为dispatch_block_flags_t的枚举,用于设置block的标记,定义如下:1
2
3
4
5
6
7
8DISPATCH_ENUM(dispatch_block_flags, unsigned long,
DISPATCH_BLOCK_BARRIER = 0x1,
DISPATCH_BLOCK_DETACHED = 0x2,
DISPATCH_BLOCK_ASSIGN_CURRENT = 0x4,
DISPATCH_BLOCK_NO_QOS_CLASS = 0x8,
DISPATCH_BLOCK_INHERIT_QOS_CLASS = 0x10,
DISPATCH_BLOCK_ENFORCE_QOS_CLASS = 0x20,
);第二种方式如下:
1
2
3dispatch_block_t dispatch_block_create_with_qos_class(dispatch_block_flags_t flags,
dispatch_qos_class_t qos_class, int relative_priority,
dispatch_block_t block);相比于
dispatch_block_create函数,这种方式在创建block的同时可以指定了相应的优先级。dispatch_qos_class_t是qos_class_t的别名,定义如下:1
2
3
4
5#if __has_include(<sys/qos.h>)
typedef qos_class_t dispatch_qos_class_t;
#else
typedef unsigned int dispatch_qos_class_t;
#endifqos_class_t是一种枚举,有以下类型:- QOS_CLASS_USER_INTERACTIVE:
user interactive等级表示任务需要被立即执行,用来在响应事件之后更新 UI,来提供好的用户体验。这个等级最好保持小规模。 - QOS_CLASS_USER_INITIATED:
user initiated等级表示任务由 UI 发起异步执行。适用场景是需要及时,结果同时又可以继续交互的时候。 - QOS_CLASS_DEFAULT:
default默认优先级 - QOS_CLASS_UTILITY:
utility等级表示需要长时间运行的任务,伴有用户可见进度指示器。经常会用来做计算,I/O,网络,持续的数据填充等任务。这个任务节能。 - QOS_CLASS_BACKGROUND:
background等级表示用户不会察觉的任务,使用它来处理预加载,或者不需要用户交互和对时间不敏感的任务。 - QOS_CLASS_UNSPECIFIED:
unspecified未指明
egg:
1
2
3
4
5
6
7
8
9
10
11dispatch_queue_t concurrentQuene = dispatch_queue_create("concurrentQuene", DISPATCH_QUEUE_CONCURRENT); dispatch_block_t block = dispatch_block_create(0, ^{
NSLog(@"normal do some thing...");
});
dispatch_async(concurrentQuene, block); dispatch_block_t qosBlock = dispatch_block_create_with_qos_class(0, QOS_CLASS_USER_INTERACTIVE, 0, ^{
NSLog(@"qos do some thing...");
});
dispatch_async(concurrentQuene, qosBlock);1
2LQHelper[1528:112987] qos do some thing...
LQHelper[1528:112985] normal do some thing...- QOS_CLASS_USER_INTERACTIVE:
2 监听 block 执行结束
有时我们需要等待特定的 block 执行完成之后,再去执行其他任务。有两种方法可以获取到指定 block 执行结束的时机。
第一种方式如下:
1
long dispatch_block_wait(dispatch_block_t block, dispatch_time_t timeout);
该函数会阻塞当前线程进行等待。传入需要设置的 block 和等待时间 timeout。timeout 参数表示函数在等待 block 执行完毕时,应该等待多久。如果执行 block 所需的时间小于 timeout,则返回 0,否则返回非 0 值。此参数也可以取常量
DISPATCH_TIME_FOREVER,这表示函数会一直等待 block 执行完,而不会超时。可以使用 dispatch_time 函数和DISPATCH_TIME_NOW常量来方便的设置具体的超时时间。 如果 block 执行完成,
dispatch_block_wait就会立即返回。不能使用dispatch_block_wait来等待同一个 block 的多次执行全部结束;这种情况可以考虑使用dispatch_group_wait来解决。也不能在多个线程中,同时等待同一个 block 的结束。同一个 block 只能执行一次,被等待一次。注意:因为
dispatch_block_wait会阻塞当前线程,所以不应该放在主线程中调用。egg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21dispatch_queue_t concurrentQuene = dispatch_queue_create("concurrentQuene", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQuene, ^{
dispatch_queue_t allTasksQueue = dispatch_queue_create("allTasksQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_block_t block = dispatch_block_create(0, ^{
NSLog(@"开始执行");
[NSThread sleepForTimeInterval:3];
NSLog(@"结束执行");
}); dispatch_async(allTasksQueue, block);
// 等待时长,10s 之后超时
dispatch_ 大专栏 GCD学习 —— 三time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC));
long resutl = dispatch_block_wait(block, timeout);
if (resutl == 0) {
NSLog(@"执行成功");
} else {
NSLog(@"执行超时");
}
});1
2
3
4
5
6
7
8执行结果:(把上面的sleepForTimeInterval:时间设置成3s)
LQHelper[1582:121193] 开始执行
LQHelper[1582:121194] 结束执行
LQHelper[1582:121193] 执行成功
执行结果:(把上面的sleepForTimeInterval:时间设置成12s)
LQHelper[1582:121193] 开始执行
LQHelper[1582:121194] 执行超时
LQHelper[1582:121193] 结束执行第二种方法如下:
1
void dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue, dispatch_block_t notification_block);
该函数接收三个参数,第一个参数是需要监视的 block,第二个参数是监听的 block 执行结束之后要提交执行的队列 queue,第三个参数是待加入到队列中的 block。 和
dispatch_block_wait的不同之处在于:dispatch_block_notify函数不会阻塞当前线程。egg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20NSLog(@"---- 开始设置任务 ----");
dispatch_queue_t serialQueue = dispatch_queue_create("com.itachi.serialqueue", DISPATCH_QUEUE_SERIAL); // 耗时任务
dispatch_block_t taskBlock = dispatch_block_create(0, ^{
NSLog(@"开始耗时任务");
[NSThread sleepForTimeInterval:2.f];
NSLog(@"完成耗时任务");
}); dispatch_async(serialQueue, taskBlock); // 更新 UI
dispatch_block_t refreshUI = dispatch_block_create(0, ^{
NSLog(@"更新 UI");
}); // 设置监听
dispatch_block_notify(taskBlock, dispatch_get_main_queue(), refreshUI);
NSLog(@"---- 完成设置任务 ----");1
2
3
4
5
6执行结果:
LQHelper[1615:127135] ---- 开始设置任务 ----
LQHelper[1615:127135] ---- 完成设置任务 ----
LQHelper[1615:127227] 开始耗时任务
LQHelper[1615:127227] 完成耗时任务
LQHelper[1615:127135] 更新 UI
3 任务的取消
iOS8 后 GCD 支持对 dispatch block 的取消。方法如下:
1 |
void dispatch_block_cancel(dispatch_block_t block); |
这个函数用异步的方式取消指定的 block。取消操作使将来执行 dispatch block 立即返回,但是对已经在执行的 dispatch block 没有任何影响。当一个 block 被取消时,它会立即释放捕获的资源。如果要在一个 block 中对某些对象进行释放操作,在取消这个 block 的时候,需要确保内存不会泄漏。
1 |
dispatch_queue_t serialQueue = dispatch_queue_create("com.itachi.serialqueue", DISPATCH_QUEUE_SERIAL);
|
1 |
执行结果: |
可见 dispatch_block_cancel 对已经在执行的任务不起作用,只能取消尚未执行的任务。
转载自GCD 之任务操作
GCD学习 —— 三的更多相关文章
- HTTP学习三:HTTPS
HTTP学习三:HTTPS 1 HTTP安全问题 HTTP1.0/1.1在网络中是明文传输的,因此会被黑客进行攻击. 1.1 窃取数据 因为HTTP1.0/1.1是明文的,黑客很容易获得用户的重要数据 ...
- TweenMax动画库学习(三)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) ...
- 多线程-GCD学习笔记
********************************* 基本概念 *********************************** 1. Grand Central Dispatch ...
- Struts2框架学习(三) 数据处理
Struts2框架学习(三) 数据处理 Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:Value ...
- 4.机器学习——统计学习三要素与最大似然估计、最大后验概率估计及L1、L2正则化
1.前言 之前我一直对于“最大似然估计”犯迷糊,今天在看了陶轻松.忆臻.nebulaf91等人的博客以及李航老师的<统计学习方法>后,豁然开朗,于是在此记下一些心得体会. “最大似然估计” ...
- DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件
DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件 本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...
- [ZZ] 深度学习三巨头之一来清华演讲了,你只需要知道这7点
深度学习三巨头之一来清华演讲了,你只需要知道这7点 http://wemedia.ifeng.com/10939074/wemedia.shtml Yann LeCun还提到了一项FAIR开发的,用于 ...
- SVG 学习<三>渐变
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- Android JNI学习(三)——Java与Native相互调用
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
随机推荐
- gcc -c xx.c 选项讲解
-c选项表示编译.汇编指定的源文件(也就是编译源文件),但是不进行链接.使用-c选项可以将每一个源文件编译成对应的目标文件. 目标文件是一种中间文件或者临时文件,如果不设置该选项,gcc 一般不会保留 ...
- LeetCode——542. 01 矩阵
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 0 0 ...
- 3)PHP基本语法和变量基础,区分大小写
(1)语法环境: PHP嵌入到html到代码中: . <?php 这里是PHP代码 ?> 标准形式: <script language='php'> 这里是PHP代码 < ...
- 元组(tuple)的用途(基础)
>>>a = 123,456,'jia',['jia','xiang'] >>>a (123, 456, 'jia', ['jia', 'xiang']) 这个带括 ...
- gMIS吉密斯十年执念:Lower Costs较低成本Better Productivity较高效率
Hello 2020! 元旦快乐!今起揭开21世纪20年代的篇章. 1. gMIS吉密斯十周年 2010-2020,十年转眼已成历史,gMIS吉密斯——通用管理信息系统(general Managem ...
- E - Apple Tree(树状数组+DFS序)
There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. ...
- 用logstash 作数据的聚合统计
用logstash 作数据的聚合统计 以spark-streaming 处理消费数据,统计日志经spark sql存储在mysql中 日志写入方式为append val wordsDataFrame ...
- DjangoBlog部署教程
本篇文章将会手把手教你如何部署DjangoBlog项目,首先介绍下我这里的基本环境,请大家仔细阅读此部分,下面的教程都会使用这些约定来介绍: 系统是ubuntu 18.04 LTS 假设你的域名是ww ...
- JS中获得指定日期前或后几天对应的日期
var d = new Date(); d.setDate(d.getDate() - 2); console.log(d.toString()); // First of month var c = ...
- php的header方法
http://www.cnblogs.com/fengzheng126/archive/2012/04/21/2461475.html