iOS单个界面多个请求的处理方案:GCD线程组+信号量
在我们实际开发的过程中一定会遇到某一个界面有几个请求的情况,而且这个问题在我之前面试的时候也有面试官问到了,我也查阅了相关资料,整理了一些东西,记录一些知识。所以我就想写这篇文章记录下来这个问题的解决方法。
1.线程组group
在遇到这种情况的时候应该大部分人都会想到线程组并发请求,注意group函数是只能并发执行任务的
通常把一组任务放到队列中,每个任务都在这个线程组,然后监听任务完成事件
最常用的几个方法:
dispatch_group_create 创建线程组
dispatch_group_async 把一个异步任务放到线程组里
dispatch_group_enter / dispatch_group_leave 这两个是必须配合使用,类似于给group添加了一个引用计数 进入为1,离开为0,当这个值为0的时候回调用dispatch_group_notify
dispatch_group_notify 用来监听任务组事件的执行完毕
dispatch_group_wait 设置等待时间。会阻塞线程,当group上任务完成或者等待时间超过设置的超时时间会结束等待
看了几个基本方法后,贴一下自己写的demo

2:信号量semaphore
这里先说明下为什么要使用信号量,调度组的效果不管用吗?其实只是我们通常开发的时候大部分用的都是AF异步请求,如果不用信号量光使用线程组的话,有可能会出现数据还没请求下来,马上收到了任务已经结束的信号执行了dispatch_group_notify刷新了UI。这样就会造成一定的错误,有兴趣的朋友可以试一下
话不多说,介绍下semaphore的几个常用方法:
dispatch_semaphore_create(long value) 创建一个带有初始值的计数信号
官方对这个函数的解释是:

需要特别说明的是,这个值不能小于0,这点官方也写到了
* The starting value for the semaphore. Passing a value less than zero will cause NULL to be returned.
如果这个值小于0的话,就会返回一个NULL值
dispatch_semaphore_signal 简单说就是给信号量+1,用来控制信号计数
dispatch_semaphore_wait 信号等待给信号减1,如果信号量小于等于0则会阻塞线程,等待。大于0的时候这个函数才会往下执行并让信号量减1

要记住的是:信号量为0则阻塞线程,大于0则不会阻塞。因此我们可以通过改变信号量的值,来控制是否阻塞线程,从而达到线程同步
说了这么多还是贴上代码吧

如果有什么不对的地方,希望大神能帮忙指出,感激不尽!最后附上demo地址:示例demo