前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS多线程-dispatch_set_target_queue

iOS多线程-dispatch_set_target_queue

作者头像
清墨
发布2019-04-09 15:47:28
1.5K0
发布2019-04-09 15:47:28
举报
文章被收录于专栏:清墨_iOS分享清墨_iOS分享

在GCD多线程的学习中,我发现了dispatch_set_target_queue这个函数。 在官方文档的释义中:https://developer.apple.com/documentation/dispatch/1452989-dispatch_set_target_queue?language=occ

对象的目标队列负责处理对象。目标队列确定调用对象终结器的队列。此外,修改一些对象的目标队列会改变它们的行为:

分派队列的优先级从其目标队列继承。使用dispatch_get_global_queue函数获得所需优先级的合适目标队列。 如果您将一个块提交给一个串行队列,而串行队列的目标队列是一个不同的串行队列,那么该块不会与提交给目标队列或具有相同目标队列的任何其他队列的块并发调用。

根据以上释义,我们可以了解到dispatch_set_target_queue可以有这两个作用: 第一:变更队列的执行优先级; 第二:目标队列可以成为原队列的执行阶层。

好的,接下来我们用代码来验证加深印象

一:变更队列的执行优先级
代码语言:javascript
复制
dispatch_queue_t q1 = dispatch_queue_create("q1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q2 = dispatch_queue_create("q2", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q3 = dispatch_queue_create("q3", DISPATCH_QUEUE_SERIAL);

dispatch_async(q1, ^{
        NSLog(@"1");
    });

    dispatch_async(q2, ^{
        NSLog(@"2");
    });

    dispatch_async(q3, ^{
        NSLog(@"3");
    });

这时代码运行输出是 1 2 3无序输出的

代码语言:javascript
复制
2019-03-26 11:52:34.281356+0800 Target[95936:2409849] 3
2019-03-26 11:52:34.281356+0800 Target[95936:2409841] 1
2019-03-26 11:52:34.281356+0800 Target[95936:2409843] 2
----------------------------------------------------------------
2019-03-26 11:54:44.154362+0800 Target[95970:2411026] 2
2019-03-26 11:54:44.154362+0800 Target[95970:2411023] 1
2019-03-26 11:54:44.154362+0800 Target[95970:2411025] 3

我们给其中q1加一个后台targetqueue,看看结果如何

代码语言:javascript
复制
    dispatch_queue_t q1 = dispatch_queue_create("q1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q2 = dispatch_queue_create("q2", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q3 = dispatch_queue_create("q3", DISPATCH_QUEUE_SERIAL);

    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_set_target_queue(q1, globalQueue);

    dispatch_async(q1, ^{
        NSLog(@"1");
    });

    dispatch_async(q2, ^{
        NSLog(@"2");
    });

    dispatch_async(q3, ^{
        NSLog(@"3");
    });

这是输出结果:

代码语言:javascript
复制
2019-03-26 11:57:14.369213+0800 Target[96036:2412962] 3
2019-03-26 11:57:14.369213+0800 Target[96036:2412960] 2
2019-03-26 11:57:14.369245+0800 Target[96036:2412963] 1
---------------------------------------------------------------
2019-03-26 11:58:50.073760+0800 Target[96061:2413923] 2
2019-03-26 11:58:50.073760+0800 Target[96061:2413921] 3
2019-03-26 11:58:50.073788+0800 Target[96061:2413922] 1

从结果可以看出,q1的目标队列是优先级低的后台队列,所以最终q1的执行在最后,也验证了dispatch_set_target_queue可以修改队列的执行优先级。

二:目标队列可以成为原队列的执行阶层。
代码语言:javascript
复制
    dispatch_queue_t q1 = dispatch_queue_create("q1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q2 = dispatch_queue_create("q2", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q3 = dispatch_queue_create("q3", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q4 = dispatch_queue_create("q3", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q5 = dispatch_queue_create("q3", DISPATCH_QUEUE_SERIAL);

    dispatch_async(q1, ^{
        NSLog(@"1");
    });

    dispatch_async(q2, ^{
        NSLog(@"2");
    });

    dispatch_async(q3, ^{
        NSLog(@"3");
    });
    
    dispatch_async(q4, ^{
        NSLog(@"4");
    });
    
    dispatch_async(q5, ^{
        NSLog(@"5");
    });

我们创建5个串行队列,并在这些串行队列中异步执行,输出一个数,这个时候输出结果是这样的:

代码语言:javascript
复制
2019-03-26 11:37:17.384915+0800 Target[95606:2398987] 1
2019-03-26 11:37:17.384915+0800 Target[95606:2398986] 5
2019-03-26 11:37:17.384936+0800 Target[95606:2398988] 3
2019-03-26 11:37:17.384964+0800 Target[95606:2398989] 2
2019-03-26 11:37:17.385006+0800 Target[95606:2398995] 4

也就是乱序,并发执行的。

我们在其中加入一个串行的目标队列如下:

代码语言:javascript
复制
    dispatch_queue_t q1 = dispatch_queue_create("q1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q2 = dispatch_queue_create("q2", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q3 = dispatch_queue_create("q3", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q4 = dispatch_queue_create("q4", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t q5 = dispatch_queue_create("q5", DISPATCH_QUEUE_SERIAL);
    
    dispatch_queue_t targetQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    
    dispatch_set_target_queue(q1, targetQueue);
    dispatch_set_target_queue(q2, targetQueue);
    dispatch_set_target_queue(q3, targetQueue);
    dispatch_set_target_queue(q4, targetQueue);
    dispatch_set_target_queue(q5, targetQueue);
    

    dispatch_async(q1, ^{
        NSLog(@"1");
    });

    dispatch_async(q2, ^{
        NSLog(@"2");
    });

    dispatch_async(q3, ^{
        NSLog(@"3");
    });

    dispatch_async(q4, ^{
        NSLog(@"4");
    });

    dispatch_async(q5, ^{
        NSLog(@"5");
    });

输出结果如下:

代码语言:javascript
复制
2019-03-26 12:03:47.953843+0800 Target[96144:2416455] 1
2019-03-26 12:03:47.954033+0800 Target[96144:2416455] 2
2019-03-26 12:03:47.954148+0800 Target[96144:2416455] 3
2019-03-26 12:03:47.954420+0800 Target[96144:2416455] 4
2019-03-26 12:03:47.955926+0800 Target[96144:2416455] 5

这样就变得有序了,从这里可以看出,串行目标队列成为了那5个队列的执行阶层。(其实第一第二个例子都是能够证明一和二的),并使队列里的任务变得有序,即串行执行。我们在实际开发中可以使用这种技术避免并发执行。

注:若将目标队列targetQueue修改为并发队列,则不会有什么实际的效果,还是并发执行

代码语言:javascript
复制
dispatch_queue_t targetQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_CONCURRENT);

2019-03-26 12:09:31.225278+0800 Target[96247:2419291] 1
2019-03-26 12:09:31.225280+0800 Target[96247:2419290] 3
2019-03-26 12:09:31.225281+0800 Target[96247:2419289] 4
2019-03-26 12:09:31.225307+0800 Target[96247:2419292] 2
2019-03-26 12:09:31.225469+0800 Target[96247:2419290] 5
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.03.26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一:变更队列的执行优先级
  • 二:目标队列可以成为原队列的执行阶层。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档