如果想在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. SpringBoot(十) 异步任务,定时任务和邮件任务

    异步任务 “异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行:异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的 ...

  2. less使用方法总结

    1 变量 我们常常在 CSS 中 看到同一个值重复多次,这样难易于代码维护. 理想状态,应是下面这样: const bgColor="skyblue"; $(".post ...

  3. Codeforces 994B. Knights of a Polygonal Table

    解题思路 将骑士按力量从小到大排序,到第i个骑士的时候,前面的i-1个骑士他都可以击败,找出金币最多的k个. 用multiset存金币最多的k个骑士的金币数,如果多余k个,则删除金币数最小的,直到只有 ...

  4. indexOf实际试用方法

    用于搜索和查找关键字个数或者位置 例如: package zifu; public class tianqi { public static void main (String args[]){ St ...

  5. maridb Error 'Operation DROP USER failed for

    数据库版本:mariadb   10.0.12 主库删除多余的用户名,因从库没有此信息造成主从故障! 报错信息如下:Error 'Operation DROP USER failed for 'use ...

  6. swfupload组件上传文件

    前段时间做文件上传用的是H5的一个插件,由于浏览器的兼容性不好,所以又换了一个Flash版本的上传文件插件,感觉这个上传插件的使用方式跟H5的差不多,有些雷同.不过,由于后续浏览不再支持Flash(略 ...

  7. ubuntu16.04 安装配置matlab+python +cuda8.0+cudnn+opencv3.1的caffe环境

    网络上有很多ubuntu上caffe配置环境的帖子,本人照着其中的许多进行了参考,都出现了或多或少的错误,很多地方也有差异. 于是自己整理了下自己的安装过程,成功进行了测试,跑通了faster-rcn ...

  8. 05 ADO.net

    ADO.NET就是一组类库 操作数据库用的.

  9. FreeCodeCamp初级算法部分学习

    Reverse a String 翻转字符串 先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串. 你的结果必须得是一个字符串 当你完成不了挑战的时候,记得开大招 ...

  10. 使用python备份指定目录并删除备份超过一定时长的文件

    #!/usr/bin/env python #-*- coding: utf-8 -*- """ @Project:Py @author: @Email: @Softwa ...