GCD队列的服务质量与优先级
-
NSQualityOfServiceUserInteractive
与用户交互的任务,这些任务通常跟 UI 级别的刷新相关,比如动画,这些任务需要在一瞬间完成;
-
NSQualityOfServiceUserInitiated
由用户发起的并且需要立即得到结果的任务,比如滑动 scroll view
时去加载数据用于后续 cell
的显示,这些任务通常跟后续的用户交互相关,在几秒或者更短的时间内完成;
-
NSQualityOfServiceUtility
一些可能需要花点时间的任务,这些任务不需要马上返回结果,比如下载的任务,这些任务可能花费几秒或者几分钟的时间;
-
NSQualityOfServiceBackground
这些任务对用户不可见,比如后台进行备份的操作,这些任务可能需要较长的时间,几分钟甚至几个小时;
-
NSQualityOfServiceDefault
优先级介于 user-initiated
和 utility
,当没有 QoS 信息时默认使用,开发者不应该使用这个值来设置自己的任务。
服务质量枚举类型
1 2 3 4 5
| QOS_CLASS_USER_INTERACTIVE QOS_CLASS_USER_INITIATED QOS_CLASS_DEFAULT QOS_CLASS_UTILITY QOS_CLASS_BACKGROUND
|
队列的优先级与服务质量的对应关系:
给队列设置QoS
dispatch_queue_attr_make_with_qos_class
dispatch_set_target_queue
GCD队列任务间依赖关系
dispatch_set_target_queue
除了能用来设置队列的 QoS 之外,还能够创建队列的层次体系。当我们想让不同队列中的任务同步的执行时,我们可以创建一个串行队列,然后将这些队列的 target 指向新创建的队列即可,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| dispatch_queue_t targetQueue = dispatch_queue_create("target_queue", DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue1 = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT); dispatch_set_target_queue(queue1, targetQueue); dispatch_set_target_queue(queue2, targetQueue); dispatch_async(queue1, ^{ NSLog(@"执行任务1,%s",dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)); sleep(1); }); dispatch_async(queue2, ^{ NSLog(@"执行任务2,%s",dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)); sleep(1); }); dispatch_async(queue2, ^{ NSLog(@"执行任务3,%s",dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)); sleep(1); });
|
注意点: 避免相互依赖,如将队列 A 的目标队列设置为队列 B,并将队列 B 的目标队列设置为队列 A。
Dispatch Group队列组
GCD 队列组,又称“调度组”,实现所有任务执行完成后有一个统一的回调。
例如:异步下载歌曲,等所有歌曲都下载完毕以后,转到主线程提示用户
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_group_async(group, queue, ^{ NSLog(@"%@,下载歌曲1",[NSThread currentThread]); }); dispatch_group_async(group, queue, ^{ NSLog(@"%@,下载歌曲2",[NSThread currentThread]); }); dispatch_group_async(group, queue, ^{ NSLog(@"%@,下载歌曲3",[NSThread currentThread]); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"%@,下载完毕",[NSThread currentThread]); });
|
队列组的原理
真正实现统一回调的操作:
1 2
| void dispatch_group_enter(dispatch_group_t group); void dispatch_group_leave(dispatch_group_t group);
|
1 2 3 4 5 6 7
| dispatch_group_async(group, queue, ^{ });
dispatch_group_enter(group); dispatch_async(queue, ^{ dispatch_group_leave(group); });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_enter(group); dispatch_async(queue, ^{ NSLog(@"%@,执行任务1",[NSThread currentThread]); dispatch_group_leave(group);
}); dispatch_group_enter(group); dispatch_async(queue, ^{ NSLog(@"%@,执行任务2",[NSThread currentThread]); dispatch_group_leave(group); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"%@,执行任务3",[NSThread currentThread]); }); dispatch_group_wait(group, DISPATCH_TIME_FOREVER); NSLog(@"%@,执行任务4",[NSThread currentThread]);
|