带你系统学习GCD(二)

欢迎走进夏天的Coding世界.
1. dispatch_barrier_async

下面通过代码对他进行解释

    dispatch_queue_t queue = dispatch_queue_create("queue.example", DISPATCH_QUEUE_CONCURRENT);

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

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

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

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

        //   dispatch_barrier_async(queue, ^{
        //     NSLog(@"I am a barrier");
        //    });

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

    dispatch_async(queue, ^{
        NSLog(@"-------------------6");
    });

    dispatch_async(queue, ^{
        NSLog(@"-------------------7");
    });

    dispatch_async(queue, ^{
        NSLog(@"-------------------8");
    });

在开发的过程中某些功能实现的时候, 我们可能需要一些特定的表现形式, 比如我想让 在 1234 都执行结束之后, 在执行之后的操作(5678), 这样使用 dispatch_barrier_async 就可以实现了, 当然使用上篇文章说到的group和dispatch_set_target_queue(不太常用)结合使用也可实现, 但是源码会很复杂, 不推荐.

2. dispatch_sync

dispatch_sync函数 “async” 异步即非同步, sync即是同步.

假设一种场景: 在执行Main Dispatch Queue 时, 使用另外一种线程 Global Dispatch Queue 进行处理, 处理结束后立即使用所得到的结果 代码示例如下

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_sync(queue, ^{
        //
    });

sync 容易造成死锁情况. 下面列举几个

情景1

dispatch_queue_t queue2 = dispatch_get_main_queue();
    dispatch_sync(queue2, ^{
        //
        NSLog(@"----------"); // 不会被执行
    });

情景2

    dispatch_queue_t queue3 = dispatch_get_main_queue();
    dispatch_async(queue3, ^{
        //
        dispatch_sync(queue3, ^{
            NSLog(@"----------");
        });
    });

情景3

    dispatch_queue_t queue4 = dispatch_queue_create("queue.example", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue4, ^{
        //
        dispatch_sync(queue4, ^{
            //
            NSLog(@"---------");
        });
    });
3. dispatch_apply

dispatch_apply 是 dispatch_sync 和 Dispatch Group 的关联API.

重复执行Block中代码. 示例如下

dispatch_queue_t queue5 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_apply(5, queue5, ^(size_t i) {
        NSLog(@"i= %zu", i);
    });

其实Dispatch_apply函数与Dispatch_sync函数相同, 都是会等待处理执行结束所以推荐这样使用示例代码如下

    dispatch_queue_t queue6 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    // 在Global Dispatch Queue 中非同步执行

    dispatch_async(queue6, ^{
        // Global Dispatch Queue 等待 Dispatch_apply 函数中的全部处理执行结束
        dispatch_apply(5, queue6, ^(size_t index) {
            //
            NSLog(@"i = %zu", index);
        });

        // 在Dispatch_apply 函数中的处理全部执行结束
        // 在Main Dispatch Queue 中非同步执行

        dispatch_async(dispatch_get_main_queue(), ^{
            // 用户界面更新等
            NSLog(@" end ");
        });
    });

原文链接

时间: 2024-12-26 02:06:40

带你系统学习GCD(二)的相关文章

带你系统学习GCD(三)

个人博客主站欢迎访问有系统GCD学习整合资料. dispatch_suspend / dispatch_resume 当使用Dispatch Queue 进行复杂处理的时候,有的时候希望不执行已追加的处理. 这种情况下可以挂起Dispatch Queue就可以, 当需要他执行的时候在执行恢复 // 挂起(可以理解为暂停) dispatch_suspend(queue); // 恢复 dispatch_resume(queue); dispatch_once 函数是在应用程序执行中只执行一次指定处

带你系统学习GCD(一)

欢迎走进夏天的Coding世界. 今天分享的关于GCD的知识, 对于GCD的说明: 开发者要做的知识定义想要执行的任务并对家到适当的Dispatch Queue中. 存在两种Dispatch Queue 见下表 Dispatch Queue的种类 说明 Serial Dispatch Queue 等待现在执行中处理结束 Concurrent Dispatch Queue 不等待现在执行中处理结束 Serial Dispatch Queue 使用一个线程 Concurrent Dispatch Q

Java I/O系统学习系列二:输入和输出

编程语言的I/O类库中常使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象.“流”屏蔽了实际的I/O设备中处理数据的细节. 在这个系列的第一篇文章:<<Java I/O系统学习系列一:File和RandomAccessFile>>中,我们讲到RandomAccessFile可以写入和读取文件,具备I/O功能,但是其只能针对文件,而I/O还涉及到很多其他场景比如网络.读取内存中的字符串等,所以Java类库中提供了一系列的类库来对其进行支持,也就是

linux系统学习(二)

文件,目录 pwd:查看当前目录 Print Working Directory cd,ls(ll),mkdir -p Change Directory List Make Directory du -sh 评估目录或者文件大小 touch 创建新文件 ln -s source dest 创建链接文件,等同于快捷方式 Link cp -rf[recurrence force]source1 source2 dest Copy rm -rf path Remove mv source dest M

系统学习Docker践行DevOps理念

感谢大家的支持,这套教程发布的有点儿晚了,希望对大家的工作有所帮助! 学习要趁早,点滴记录,学习就是进步! 不要到处找了,抓紧提升自己. 下载地址:版权保护,不再提供网络下载地址. 请联系本文作者或者关注公众号:菜鸟奋斗 系统学习Docker 践行DevOps理念 Docker代表的容器技术是近两年的大热技术,和人工智能.区块链等热点不同,容器技术的门槛并不高,每一个开发.测试.运维人员都能在日常工作中掌握和使用,是当今IT从业人员的必备技能之一.本课程会带大家系统学习什么是容器,如何创建容器.

系统学习Docker 践行DevOps理念

Docker代表的容器技术是近两年的大热技术,和人工智能.区块链等热点不同,容器技术的门槛并不高,每一个开发.测试.运维人员都能在日常工作中掌握和使用,是当今IT从业人员的必备技能之一.本课程会带大家系统学习什么是容器,如何创建容器.管理容器:学习容器技术的各个细节(网络/存储/服务编排/监控),学习如何通过容器进行CI/CD持续集成,持续部署.学习Docker,让你成为更加优秀的IT工程师. 原文地址:https://www.cnblogs.com/abc1168/p/9532341.html

从零开始系统学习C/C++,C++系统学习路线

C++常用在后端服务器,移动互联网后端,经典Windows界面开发,移动互联网端界面开发,跨平台界面开发,图形分析,系统架构,应用设计,还有现在最为流行的分布架构等一些新的技术领域,C/C++工程师必备知识的思维导图. 从零开始系统学习C/C++,C++系统学习路线一.初级入门阶段 在入门之初,首先要做的是通过C/C++语言的学习培养编程思维和动手能力,深刻理解面向过程和面向对象的思想方法.这个阶段你需要学习: ① C语言 数据类型.变量.内存布局.指针基础: 字符串.一维数组.二维数组: 一级

C语言学习(二)——字符串和格式化输入输出

C语言学习(二)——字符串和格式化输入输出 1.char数组类型和空字符 C没有为字符串定义专门的变量类型,而是把它存储在char数组里.数组的最后一个位置显示字符\0.这个字符就是空字符,C用它来标记字符串的结束,其ASCII码的值为(或者等同于)0.C的字符串存储时通常以这个空字符结束,该字符的存在意味着数组的单元数必须至少比要存储的字符数多1.计算机可以自己处理大多数这些细节问题(例如,scanf( )会添加'\0'使得数组内容成为C字符串). 2.strlen( )函数与sizeof运算

Android学习笔记二十之Toast吐司、Notification通知、PopupWindow弹出窗

Android学习笔记二十之Toast吐司.Notification通知.PopupWindow弹出窗 Toast吐司 Toast吐司是我们经常用到的一个控件,Toast是AndroidOS用来显示消息的一种机制,它与Dialog不同,Toast不会获取到焦点,通常显示一段时间之后就会自动消失,下面我们来介绍Toast的几种常用方式: 第一种,默认显示方式,也是最常用的方式: Toast.makeText(MainActivity.this, "这是默认的显示方式", Toast.LE