使用GCD中的dispatch_semaphore(信号量)处理一个界面多个请求(把握AFNet网络请求完成的正确时机)

对于iOS开发中的网络请求模块,AFNetworking的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?什么是信号量?git

1.先说什么是信号量。github

信号量:就是一种可用来控制访问资源的数量的标识,设定了一个信号量,在线程访问以前,加上信号量的处理,则可告知系统按照咱们指定的信号量数量来执行多个线程。其实,这有点相似锁机制了,只不过信号量都是系统帮助咱们处理了,咱们只须要在执行线程以前,设定一个信号量值,而且在使用时,加上信号量处理方法就好了。网络

信号量有3个函数,分别是:多线程

建立信号量,参数:信号量的初值 异步

dispatch_semaphore_create(信号量值)函数

等待下降信号量  dispatch_semaphore_wait(信号量,等待时间)spa

提升信号量 dispatch_semaphore_signal(信号量)线程

2.在真实开发中,咱们一般会遇到以下问题:3d

①一个界面存在多个请求,但愿全部请求完成以后才去进行下面的操做。blog

解决方案很容易想到经过线程组进行实现。代码以下:

 


 

打印结果以下:


打印结果观察可能并无什么问题,但须要注意的是request1 request2 request3等在真实开发中一般对应为某个网络请求。而网络请求一般为异步,那这时是否还会有一样结果呢?

咱们换成真是的网络请求再看一下。

对于App请求数据大部分人都会选择AFNetworking。使用AFN异步请求,请求的数据返回后,就刷新相关UI。若是某一个页面有多个网络请求,咱们假设有三个请求,request一、request二、request3,并且UI里的数据必须等到request一、request二、request3所有完成后刷新后才显示。

这里咱们书写一个网络请求通用方法。使用咱们最经常使用的AFNet请求,方法以下:

 


request2 request3分别请求对应的下面的数据,就不重复写了,文章末尾会把demo地址附上,感兴趣的能够下载来看一下。

打印结果以下:

 


运行后立刻接收到了线程组完成的提示,以后数据才依次请求下来,很明显三个单纯的AFNetworking请求已经不能知足咱们的需求了。线程组完成时并无在咱们但愿的时候给予通知。在真实开发中会形成的问题为多个请求均加载完成,但界面已在未获得数据前提早刷新致使界面空白。

这里咱们就要借助GCD中的信号量dispatch_semaphore进行实现,即营造线程同步状况。

dispatch_semaphore信号量为基于计数器的一种多线程同步机制。用于解决在多个线程访问共有资源时候,会由于多线程的特性而引起数据出错的问题。

若是semaphore计数大于等于1,计数-1,返回,程序继续运行。若是计数为0,则等待。

dispatch_semaphore_signal(semaphore)为计数+1操做。dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)为设置等待时间,这里设置的等待时间是一直等待。

把网络请求进行以下修改:

 


 

经过信号量dispatch_semaphore完美的解决了此问题,而且网络请求仍为异步,不会堵塞当前主线程。

实例地址:点击去下载

相关文章
相关标签/搜索