如果想在dispatch_queue中所有的任务执行完成后在做某种操作,在串行队列中,可以把该操作放到最后一个任务执行完成后继续,但是在并行队列中怎么做呢。这就有dispatch_group 成组操作。

有一个需求是,是想发出三个网络请求,当三个请求全部执行返回结果的时候再做一些操作,不论返回的是失败还是成功都算返回结果。

下面是dispatch_group异步并行执行网络请求。

执行完三个异步成组发送请求全部结束后进入到dispatch_group_notify执行最终的那个操作,但是这个时候可以看一下打印结果:

_responseGetVisaGetDianPingList = nil这个你就当做是不为nil的,因为是我为了测试故意置为nil的。我们暂且关注_responseGetVisaDetail = nil,其实这里置为nil是因为成组操作的第一个操作还没有执行结束,不是因为结束了返回失败所以是nil,这个大家不要混淆。正常来说我们想要的结果是,三个请求网络请求执行结束的时候才进入dispatch_group_notify,并且三个response都应该是不为nil有值的。我来解释下,这里为什么到dispatch_group_notify了,但是第一个请求还没有返回结束,这是因为上面这种写法遵守的成组全部执行结束指的是三个block写的代码直观进行执行完就不算了,不包含block内部的异步请求,因此会出现这中间结果。所以我们应该换一种写法。下图:

这种dispatch_group_enter和dispatch_group_leave是成对出现的,当进入一个操作后,在适当的位置加上dispatch_group_leave,比如在这里,进入第一个enter执行requestGetVisaDetail操作,那么紧跟的这个block,是当执行结束(成功或失败)后会立刻执行,是真正关注包含了异步的情况,所以这里当执行到断点的时候,结果如下是正确的:

_responseGetVisaGetDianPingList = nil这个忽略,其他的都是正常的。验证正确,因此在成组加载异步请求的时候一定到区分开。避免入坑。

今天16年7月9号,又发现了一个坑,在这里做一个解释。

其实这种成组一共3个的发送请求,执行到dispatch_group_notify的时候,前面三个请求必然全部请求有结果了才执行到了这里,但是呢,之前一直有个点理解错了,之前一直以为第一个请求发送有结果了,才去执行第二个请求,接着同样,但是呢,就是因为这个理解失误才导致问题。其实实际上是这样执行的,当第一个请求发出去之后,因为是异步,第二个请求不会等到第一个请求有结果了才去发送第二个请求,第二个dispatch_group_enter和dispatch_group_leave之间的[self requestCrossRecommoned]仍然会执行,所以第三个请求也是不会因为等到第一个和第二个请求有结果了才去执行请求,但是呢问题来了,因为第三个请求会有两个请求参数是第一个请求的结果response的字段,这样就会有问题啦,因为当第三个请求发起的时候这个时候,第一个请求一般情况下都是没有返回结果的,还没请求结束,这样第三个请求的请求参数会为nil,导致结果和预期的不一致。那么怎么解决的呢?就是把第三个请求放到第一个请求结束,有结果之后,我是把它放到第一个请求结束成功里面了,这样虽然第二个请求有可能是第一个执行结束的,第一个第二个执行结束有结果,因为第三个请求放在第二个结果结束的成功response里面,所以是最后一个发起的,但是呢,这个时候第三个请求参数是存在的。因此问题解决,三个请求全部执行结束,才会走dispatch_group_notify。其实在这个解决方案之前,我是单单把第三个请求[self requestCrossRecommoned]放到第一个请求里面的,没有用dispatch_group_enter和dispatch_group_leave包装起来,所以会导致当执行到dispatch_group_notify的时候,第三个请求还没有执行结束还没有结果。所以我猜想啊,这个dispatch_group_enter和dispatch_group_leave只会保证一个方法内部的请求执行结束,并不会保证里面再有一层的请求结束才执行dispatch_group_notify。

下面是解决后的方案,把grouop传到第一个请求方法里面,作为第三个请求的包装。

下面一张图就是放在第一个请求的执行结束的成功response里面,并且用dispatch_group_enter和dispatch_group_leave包了起来,这样可以保证dispatch_group_notify执行起必须是这三个请求全部执行结束。

dispatch_group_t踩过的坑的更多相关文章

  1. 项目中踩过的坑之-sessionStorage

    总想写点什么,却不知道从何写起,那就从项目中踩过的坑开始吧,希望能给可能碰到相同问题的小伙伴一点帮助. 项目情景: 有一个id,要求通过当前网页打开一个新页面(不是当前页面),并把id传给打开的新页面 ...

  2. web开发实战--弹出式富文本编辑器的实现思路和踩过的坑

    前言: 和弟弟合作, 一起整了个智慧屋的小web站点, 里面包含了很多经典的智力和推理题. 其实该站点从技术层面来分析的话, 也算一个信息发布站点. 因此在该网站的后台运营中, 富文本的编辑器显得尤为 ...

  3. "开发路上踩过的坑要一个个填起来————持续更新······(7月30日)"

    欢迎转载,请注明出处! https://gii16.github.io/learnmore/2016/07/29/problem.html 踩过的坑及解决方案记录在此篇博文中! 个人理解,如有偏颇,欢 ...

  4. 【转载】Fragment 全解析(1):那些年踩过的坑

    http://www.jianshu.com/p/d9143a92ad94 Fragment系列文章:1.Fragment全解析系列(一):那些年踩过的坑2.Fragment全解析系列(二):正确的使 ...

  5. Redis Cluster踩过的坑

    Redis Cluster踩过的坑请参考如下链接:http://www.iteye.com/blogs/subjects/Redis_Cluster_Devops

  6. 第八篇:web之前端踩的一些坑

    前端踩的一些坑   前端踩的一些坑 本节内容 事件代理 清除标签的所有事件 bootstrap的模态框自定义方法 ajax在django里面实现post提交 ajax提交数据嵌套 1.事件代理 之前写 ...

  7. 使用ffmpeg视频编码过程中踩的一个坑

           今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果:                   ...

  8. 那些年踩过的坑之:first-child伪类选择器

    原文:那些年踩过的坑之:first-child伪类选择器 :first-child 选择器用于选取属于其父元素的首个子元素的指定选择器.——w3school 嗯,乍一看好像说的不是很明白,因此这个选择 ...

  9. 《C++之那些年踩过的坑(二)》

    C++之那些年踩过的坑(二) 作者:刘俊延(Alinshans) 本系列文章针对我在写C++代码的过程中,尤其是做自己的项目时,踩过的各种坑.以此作为给自己的警惕. 今天讲一个小点,虽然小,但如果没有 ...

随机推荐

  1. firstChild与firstElementChild

    相同点: 都是获取父元素下的第一个节点对象 不同点: firstChild: IE6.7.8 第一个元素节点; 非IE6.7.8:返回第一个元素节点或文本节点 firstElementChild: I ...

  2. E5中遍历数组的方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. http接口服务方结合策略模式实现总结

    在项目中,我们经常会使用到http+xml的接口,而且不仅仅的是一个,可能会有多个http的接口需要实时的交互.但是http接口的接收消息的公共部分是一样的,只有每个接口的报文解析和返回报文是不同的, ...

  4. UNP学习笔记4——I/O复用:select和poll函数

    1 概述 之间的学习中发现,传统的阻塞式系统调用不仅浪费进程运行时间,而且会带来狠毒问题.因此进程需要有一种预先告知内核的能力,使得内核一旦发现进程指定的一个或者多个I/O条件就绪,它就通知进程.这个 ...

  5. 洛谷1613 跑路 倍增 + Floyd

    首先,我们一定要认识到本题中的最短时间所对应的道路不一定是在起点到终点的最短路.例如,起点到终点的最短路为 151515 ,那么对 151515 进行二进制拆分的话是 111111111111 ,这时 ...

  6. JS table分页

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="paging3.aspx.c ...

  7. 再次理解JS的prototype,__proto__和constructor

    个人总结: 下面这篇文章很好的讲解了js原型,原型链,个人的总结是要记住这三个属性 prototype.__proto__和constructor 首先明确,js中一切都是对象object(A). ( ...

  8. pupload上传插件问题整理

    前些日子公司网站需要开发一个类似与百度文库上传文档的功能,实现文档的批量上传.展示以及继续上传的功能.开发完成后,通过在多版浏览器下的使用,发现了一系列问题,特总结于下,以免来者在这些问题上耗费太多时 ...

  9. [TJOI2015]线性规划

    题目:洛谷P3973.BZOJ3996. 题目大意:给你n,参数b[][]和c[](里面的数均>0),要你求一个数组A[](0/1,1表示选择),已知:1. 若同时选择X和Y,获得B[x][y] ...

  10. [CodeForces]529B Group Photo 2

    AK爷GhostCai的电脑又蓝屏了Orz 贪心题,确定一个maxh,限定h不大于一个值.枚举maxh. check的时候的细节很多: 1.h>maxh但w<maxh交换的时候需要占用交换 ...