AFNetworking筆記

最近在看runloop時(shí)看到不少blog都說(shuō)AFNetworking,有使用到runloop創(chuàng)建一個(gè)子線程并保持線程不斷循環(huán)。

我在我的項(xiàng)目(AF 3.x)中尋找并沒(méi)有找到相關(guān)方法,之后在AF 2.x中找到了相關(guān)方法。?

AF 2.x基于NSURLConnection包裝的重要對(duì)象,由于iOS9-NSURLConnection已經(jīng)不能使用,AFNetworking在3.x版本中刪除了基于 NSURLConnection API的所有支持。如果項(xiàng)目以前使用過(guò)這些API,那么我們需要升級(jí)到基于 NSURLSession 的API的AFNetworking的版本。

線程 ?摘自 ( ?AFNetworking2.0源碼解析 ? bang’s blog

來(lái)看看NSURLConnection發(fā)送請(qǐng)求時(shí)的線程情況,NSURLConnection是被設(shè)計(jì)成異步發(fā)送的,調(diào)用了start方法后,NSURLConnection會(huì)新建一些線程用底層的CFSocket去發(fā)送和接收請(qǐng)求,在發(fā)送和接收的一些事件發(fā)生后通知原來(lái)線程的Runloop去回調(diào)事件。

NSURLConnection的同步方法sendSynchronousRequest方法也是基于異步的,同樣要在其他線程去處理請(qǐng)求的發(fā)送和接收,只是同步方法會(huì)手動(dòng)block住線程,發(fā)送狀態(tài)的通知也不是通過(guò)RunLoop進(jìn)行。

使用NSURLConnection有幾種選擇:

A.在主線程調(diào)異步接口

若直接在主線程調(diào)用異步接口,會(huì)有個(gè)Runloop相關(guān)的問(wèn)題

當(dāng)在主線程調(diào)用[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]時(shí),請(qǐng)求發(fā)出,偵聽任務(wù)會(huì)加入到主線程的Runloop下,RunloopMode會(huì)默認(rèn)為NSDefaultRunLoopMode。這表明只有當(dāng)前線程的Runloop處于NSDefaultRunLoopMode時(shí),這個(gè)任務(wù)才會(huì)被執(zhí)行。但當(dāng)用戶滾動(dòng)tableview或scrollview時(shí),主線程的Runloop是處于NSEventTrackingRunLoopMode模式下的,不會(huì)執(zhí)行NSDefaultRunLoopMode的任務(wù),所以會(huì)出現(xiàn)一個(gè)問(wèn)題,請(qǐng)求發(fā)出后,如果用戶一直在操作UI上下滑動(dòng)屏幕,那在滑動(dòng)結(jié)束前是不會(huì)執(zhí)行回調(diào)函數(shù)的,只有在滑動(dòng)結(jié)束,RunloopMode切回NSDefaultRunLoopMode,才會(huì)執(zhí)行回調(diào)函數(shù)。蘋果一直把動(dòng)畫效果性能放在第一位,估計(jì)這也是蘋果提升UI動(dòng)畫性能的手段之一。

所以若要在主線程使用NSURLConnection異步接口,需要手動(dòng)把RunloopMode設(shè)為NSRunLoopCommonModes。這個(gè)mode意思是無(wú)論當(dāng)前Runloop處于什么狀態(tài),都執(zhí)行這個(gè)任務(wù)。

B.在子線程調(diào)同步接口

若在子線程調(diào)用同步接口,一條線程只能處理一個(gè)請(qǐng)求,因?yàn)檎?qǐng)求一發(fā)出去線程就阻塞住等待回調(diào),需要給每個(gè)請(qǐng)求新建一個(gè)線程,這是很浪費(fèi)的,這種方式唯一的好處應(yīng)該是易于控制請(qǐng)求并發(fā)的數(shù)量。

C.在子線程調(diào)異步接口

子線程調(diào)用異步接口,子線程需要有Runloop去接收異步回調(diào)事件,這里也可以每個(gè)請(qǐng)求都新建一條帶有Runloop的線程去偵聽回調(diào),但這一點(diǎn)好處都沒(méi)有,既然是異步回調(diào),除了處理回調(diào)內(nèi)容,其他時(shí)間線程都是空閑可利用的,所有請(qǐng)求共用一個(gè)響應(yīng)的線程就夠了。

AFNetworking用的就是第三種方式,創(chuàng)建了一條常駐線程專門處理所有請(qǐng)求的回調(diào)事件,這個(gè)模型跟nodejs有點(diǎn)類似。網(wǎng)絡(luò)請(qǐng)求回調(diào)處理完,組裝好數(shù)據(jù)后再給上層調(diào)用者回調(diào),這時(shí)候回調(diào)是拋回主線程的,因?yàn)橹骶€程是最安全的,使用者可能會(huì)在回調(diào)中更新UI,在子線程更新UI會(huì)導(dǎo)致各種問(wèn)題,一般使用者也可以不需要關(guān)心線程問(wèn)題。

NSURLSession

絡(luò)設(shè)置:參考NSURLConnection中的設(shè)置項(xiàng)。

1. 創(chuàng)建一個(gè)NSURLSession,系統(tǒng)提供了兩個(gè)創(chuàng)建方法:

sessionWithConfiguration:

sessionWithConfiguration:delegate:delegateQueue:

第一個(gè)粒度較低就是根據(jù)剛才創(chuàng)建的Configuration創(chuàng)建一個(gè)Session,系統(tǒng)默認(rèn)創(chuàng)建一個(gè)新的OperationQueue處理Session的消息。

第二個(gè)粒度比較高,可以設(shè)定回調(diào)的delegate(注意這個(gè)回調(diào)delegate會(huì)被強(qiáng)引用),并且可以設(shè)定delegate在哪個(gè)OperationQueue回調(diào),如果我們將其設(shè)置為[NSOperationQueue mainQueue]就能在主線程進(jìn)行回調(diào)非常的方便。OperationQueue不傳系統(tǒng)會(huì)自動(dòng)在子線程返回,AF3.x在這里傳入一個(gè)子操作隊(duì)列,讓其回調(diào)在同一個(gè)操作隊(duì)列中進(jìn)行。

2.創(chuàng)建一個(gè)NSURLRequest調(diào)用剛才的NSURLSession對(duì)象提供的Task函數(shù),創(chuàng)建一個(gè)NSURLSessionTask。

根據(jù)職能不同Task有三種子類:

NSURLSessionUploadTask:上傳用的Task,傳完以后不會(huì)再下載返回結(jié)果;

NSURLSessionDownloadTask:下載用的Task;

NSURLSessionDataTask:可以上傳內(nèi)容,上傳完成后再進(jìn)行下載。

得到的Task,調(diào)用resume開始工作,默認(rèn)是掛起的。


NSURLSession是線程安全的,在多線程方面的支持也比URLConnection要好。

NSURLSessionTask會(huì)在子線程工作,不會(huì)阻礙主線程。在AF3.0沒(méi)有再使用runloop來(lái)接受回調(diào)事件,而是創(chuàng)建NSURLSession時(shí),傳入了一個(gè)子操作隊(duì)列,所有的回調(diào)事件都在這個(gè)操作隊(duì)列中處理。Runloop的模式不會(huì)影響它的回調(diào)。

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

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

  • 最近在看runloop時(shí)看到不少blog都說(shuō)AFNetworking,有使用到runloop創(chuàng)建一個(gè)子線程并保持線...
    1bf235f48fa8閱讀 185評(píng)論 0 0
  • 1.整體架構(gòu) 2.核心類 AFURLSessionManager 2.1.初始化方法 init 1)首先我們要明確...
    西門吹灰閱讀 663評(píng)論 0 0
  • 一、RunLoop 的概念 字面意思是“消息循環(huán)、運(yùn)行循環(huán)”,RunLoop 實(shí)際上就是一個(gè)事件循環(huán)對(duì)象,這個(gè)對(duì)象...
    風(fēng)輕魚蛋閱讀 573評(píng)論 0 1
  • 今天上午和老師錄掌門網(wǎng)絡(luò)課!錄完劉中午一點(diǎn)多了,寫了寫和別的單位的合作價(jià)格表,練了半個(gè)小時(shí)瑜伽! ...
    yogaxiaxia日記閱讀 355評(píng)論 0 2
  • 我們的世界像一個(gè)迷宮,而工作與生活就像是奶酪,他們總是在不斷變化著,而我們必須得不停的在迷宮中搜尋著新的奶酪...
    萊開心閱讀 1,807評(píng)論 4 6

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