iOS开发

iOS单个界面多个请求的处理方案:GCD线程组+信号量

2019-04-26  本文已影响515人  TonyTT

在我们实际开发的过程中一定会遇到某一个界面有几个请求的情况,而且这个问题在我之前面试的时候也有面试官问到了,我也查阅了相关资料,整理了一些东西,记录一些知识。所以我就想写这篇文章记录下来这个问题的解决方法。

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

这里就是列举了三个请求把三个异步任务添加到线程组,其中队列我用的是全局并发队列,在执行完任务的时候会触发dispatch_group_notify这个方法,然后在主线程刷新UI

2:信号量semaphore

这里先说明下为什么要使用信号量,调度组的效果不管用吗?其实只是我们通常开发的时候大部分用的都是AF异步请求,如果不用信号量光使用线程组的话,有可能会出现数据还没请求下来,马上收到了任务已经结束的信号执行了dispatch_group_notify刷新了UI。这样就会造成一定的错误,有兴趣的朋友可以试一下

话不多说,介绍下semaphore的几个常用方法:

dispatch_semaphore_create(long value)  创建一个带有初始值的计数信号

官方对这个函数的解释是:

意思大概就是当两个线程需要去协调某一个特定事件任务的时候,给这个函数value赋0的值。如果是要管理有限的资源池,则传一个大于0的值,这个池的大小也就是这个值的大小,相当于我开几条线程我就赋什么值

需要特别说明的是,这个值不能小于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则阻塞线程,大于0则不会阻塞。因此我们可以通过改变信号量的值,来控制是否阻塞线程,从而达到线程同步

说了这么多还是贴上代码吧

其他两个请求也是一样,就不贴了,而且代码我也写了注释,结尾我会加上示例demo的地址,有兴趣的朋友可以下下来看下

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

上一篇 下一篇

猜你喜欢

热点阅读