使用GCD中的dispatch_semaphore(信號(hào)量)處理一個(gè)界面多個(gè)請求(把握AFNet網(wǎng)絡(luò)請求完成的正確時(shí)機(jī))

對于iOS開發(fā)中的網(wǎng)絡(luò)請求模塊,AFNetworking的使用應(yīng)該是最熟悉不過了,但你是否把握了網(wǎng)絡(luò)請求正確的完成時(shí)機(jī)?什么是信號(hào)量?

1.先說什么是信號(hào)量。

信號(hào)量:就是一種可用來控制訪問資源的數(shù)量的標(biāo)識(shí),設(shè)定了一個(gè)信號(hào)量,在線程訪問之前,加上信號(hào)量的處理,則可告知系統(tǒng)按照我們指定的信號(hào)量數(shù)量來執(zhí)行多個(gè)線程。其實(shí),這有點(diǎn)類似鎖機(jī)制了,只不過信號(hào)量都是系統(tǒng)幫助我們處理了,我們只需要在執(zhí)行線程之前,設(shè)定一個(gè)信號(hào)量值,并且在使用時(shí),加上信號(hào)量處理方法就行了。

信號(hào)量有3個(gè)函數(shù),分別是:

創(chuàng)建信號(hào)量,參數(shù):信號(hào)量的初值?

dispatch_semaphore_create(信號(hào)量值)

等待降低信號(hào)量 ?dispatch_semaphore_wait(信號(hào)量,等待時(shí)間)

提高信號(hào)量?dispatch_semaphore_signal(信號(hào)量)

2.在真實(shí)開發(fā)中,我們通常會(huì)遇到如下問題:

①一個(gè)界面存在多個(gè)請求,希望所有請求完成之后才去進(jìn)行下面的操作。

解決方案很容易想到通過線程組進(jìn)行實(shí)現(xiàn)。代碼如下:


打印結(jié)果如下:

打印結(jié)果觀察可能并沒有什么問題,但需要注意的是request1 request2 request3等在真實(shí)開發(fā)中通常對應(yīng)為某個(gè)網(wǎng)絡(luò)請求。而網(wǎng)絡(luò)請求通常為異步,那這時(shí)是否還會(huì)有同樣結(jié)果呢?

我們換成真是的網(wǎng)絡(luò)請求再看一下。

對于App請求數(shù)據(jù)大部分人都會(huì)選擇AFNetworking。使用AFN異步請求,請求的數(shù)據(jù)返回后,就刷新相關(guān)UI。如果某一個(gè)頁面有多個(gè)網(wǎng)絡(luò)請求,我們假設(shè)有三個(gè)請求,request1、request2、request3,而且UI里的數(shù)據(jù)必須等到request1、request2、request3全部完成后刷新后才顯示。

這里我們書寫一個(gè)網(wǎng)絡(luò)請求通用方法。使用我們最常用的AFNet請求,方法如下:


request2 request3分別請求對應(yīng)的下面的數(shù)據(jù),就不重復(fù)寫了,文章末尾會(huì)把demo地址附上,感興趣的可以下載來看一下。

打印結(jié)果如下:


運(yùn)行后馬上接收到了線程組完成的提示,之后數(shù)據(jù)才依次請求下來,很明顯三個(gè)單純的AFNetworking請求已經(jīng)不能滿足我們的需求了。線程組完成時(shí)并沒有在我們希望的時(shí)候給予通知。在真實(shí)開發(fā)中會(huì)造成的問題為多個(gè)請求均加載完成,但界面已在未得到數(shù)據(jù)前提前刷新導(dǎo)致界面空白。

這里我們就要借助GCD中的信號(hào)量dispatch_semaphore進(jìn)行實(shí)現(xiàn),即營造線程同步情況。

dispatch_semaphore信號(hào)量為基于計(jì)數(shù)器的一種多線程同步機(jī)制。用于解決在多個(gè)線程訪問共有資源時(shí)候,會(huì)因?yàn)槎嗑€程的特性而引發(fā)數(shù)據(jù)出錯(cuò)的問題。

如果semaphore計(jì)數(shù)大于等于1,計(jì)數(shù)-1,返回,程序繼續(xù)運(yùn)行。如果計(jì)數(shù)為0,則等待。

dispatch_semaphore_signal(semaphore)為計(jì)數(shù)+1操作。dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)為設(shè)置等待時(shí)間,這里設(shè)置的等待時(shí)間是一直等待。

把網(wǎng)絡(luò)請求進(jìn)行如下修改:


通過信號(hào)量dispatch_semaphore完美的解決了此問題,并且網(wǎng)絡(luò)請求仍為異步,不會(huì)堵塞當(dāng)前主線程。

實(shí)例地址:點(diǎn)擊去下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容