使用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完美的解決了此問題,而且網絡請求仍爲異步,不會堵塞當前主線程。

實例地址:點擊去下載

相關文章
相關標籤/搜索