不少時候,AFNetworking都是目前iOS
開發者網絡庫中的不二選擇。Github
上2W+
的star
數足見其流行程度。而從iOS7.0
開始,蘋果推出了新的網絡庫繼承者NSURLSession
後,AFNetworking
也堅決果斷地加入了對其的支持。3.0+
更加只是提供了NSURLSession
的支持。git
咱們使用AFNetworking
的時候,可能會有不少的朋友都會採用如下的寫法:github
AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager]; sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer]; sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer]; [sessionManager GET:urlString parameters:parameters progress:progressBlock success:successHandler failure:failureHandler];
大概能夠描述一下這個過程,每次開啓一個網絡請求時,首先新建一個AFHTTPSessionManager
,而後將相關的requestSerializer
和reponseSerializer
賦值;最後發起相應的GET/POST
等請求。sql
而若是是直接採用NSURLSession
來請求網絡呢,咱們則常常會採用如下的寫法:ruby
NSURLSession *session = [NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:completionHandler]; [dataTask resume];
這個過程其實和上面的基本一致。新建一個Session
,而後新建task
,激活task
,完成網絡請求。服務器
那麼如今問題來了。爲何每次都須要新建一個SessionManager/Session
?若是在多個Task
請求的狀況下,若是採起一個共享的SessionManager/Session
是否可行?若是可行,與以前每次新建SessionManager/Session
相比,孰優孰劣?網絡
本篇文章會告訴您:
1. 爲何要使用NSURLSession而不是NSURLConnection
2. 爲何要用共享的SessionManager/Session
,而不是每次都啓動一個新的 session
NSURLSession
在iOS7.0
時被Apple提出後,雖然Apple一直對其良好的API
設計大力推廣,然而其可以達到的效果,彷佛一直都和NSURLConnection
不相伯仲。 架構
特別是在網絡的Dependecy
依賴處理上,因爲AFNetworking
優秀的架構設計,NSURLSession
甚至還不如NSURLConnection
好用。那麼,有什麼理由切換到NSURLSession
? 2015年的WWDC彷佛告訴了咱們答案。 併發
HTTP /2
, 2015年5月RFC 7540正式發表的下一代HTTP協議,是1999年來HTTP 1.1
發佈後的首個更新。相對於前一個版本,HTTP /2
以快
著稱。以下圖,對相同圖片、相同服務器的下載,在不一樣協議下所需的時間: app
這裏咱們並不打算展開HTTP /2
的原理,有興趣的同窗能夠Google之。根據2015的WWDC Session711,咱們知道iOS9+
,NSURLSession
開始正式支持HTTP /2
,也就意味着你的網絡鏈接速度也能夠有如上圖那樣的提高。
更人性化更優秀的API
設計,HTTP /2
的支持,這是否能成爲你使用NSURLSession
的理由?至少它們成爲了說服個人理由。
在回答這個問題之前,咱們先來聊聊網絡的通信協議。咱們也都知道,HTTP
協議是基於TCP
協議的。因此在每次的HTTP
請求以前,客戶端和服務器端,都先須要通過TCP
鏈接的三次握手,即每次請求以前,網絡的數據都已經在客戶端和服務器端之間來回了三次。以下圖:
事實上在HTTP 0.9
, HTTP 1.0
協議的時代,每次HTTP的請求,都須要先通過TCP
的鏈接,而後纔開始HTTP
的請求,這樣一個流程圖,咱們能夠經過抓包看到:
那麼,爲了讓咱們的請求更快,避免每次都產生一個TCP
三次握手,成了一個優化的選項。因而在HTTP 1.1
中,出現了Connection: keep-alive
這個選項。這個優化選項,可使得客戶端和服務器端複用一個TCP
鏈接,從而減少每次的網絡請求時間。
聊到這裏,本章提出的問題,其實答案已經逐漸明瞭了。沒錯,共享的Session
將會複用TCP
的鏈接,而每次都新建Session
的操做將致使每次的網絡請求都開啓一個TCP
的三次握手。
從上面兩張圖,咱們能夠清晰地看到,一樣都是兩次HTTP請求,共享Session
的代碼在第二次網絡請求時少了TCP
的三次握手的過程。即加速了整個網絡的請求時間。
事實上,蘋果的文檔中,還對一個服務器最高的TCP
併發有相應的描述:
HTTPMaximumConnectionsPerHost Property
The maximum number of simultaneous connections to make to a given host.
Declaration
SWIFT
var HTTPMaximumConnectionsPerHost: Int
OBJECTIVE-C
@property NSInteger HTTPMaximumConnectionsPerHost
Discussion
This property determines the maximum number of simultaneous connections made to each host by tasks within sessions based on this configuration.
This limit is per session, so if you use multiple sessions, your app as a whole may exceed this limit. Additionally, depending on your connection to the Internet, a session may use a lower limit than the one you specify. The default value is 6 in OS X, or 4 in iOS. Availability Available in iOS 7.0 and later.
咱們能夠看到,默認配置下,iOS
對於同一個IP服務器的併發最大爲4
,OS X
爲6
。而若是你沒有使用共享的Session
,則可能會超過這個數。
所以,若是能用共享的Session
,仍是用共享的吧。有些許的網絡加速,也是一件不錯的事情,您說呢?