一、統一網絡入口;編程
二、統一共性處理;網絡
在iOS開發中,與直接使用蘋果框架中提供的NSURLConnection或NSURLSession進行網絡請求相比,使用AFNetworking會有哪些好處?當同時發起多個網絡請求AFNetworking是如何實現併發的,在併發的時候,AFNetworking是如何管理線程的?蘋果重構NSURLConnetion推出新的網絡加載系統NSURLSession解決了什麼問題或者是與NSURLConnection相比NSURLSession有好些好處?上面問題的答案會貫穿在這篇文章中(本篇文章只涉及了與操做隊列,多線程相關的分析)。session
NSURLConnection提供了兩個類方法用於發起同步或異步請求,對於異步請求來講必然是在子線程中發起,若在主線程中發起異步網絡請求會形成主線程阻塞,界面無響應,這就涉及到多線程編程。但多線程編程是一門很是細緻的活,要考慮不少的問題,好比線程的生命週期,多線程資源競爭,加鎖,避免死鎖,稍不留意就會踩到坑裏。好在蘋果的接口使用極其方便,你甚至不須要理解多線程就能輕鬆使用上多線程了,發起異步請求的接口內部已經實現了多線程相關的操做。越是高級的接口,其隱藏的細節就越多,對於開發者來講固然是很方便,但若還能對其實現有所理解那就更完美了。當子線程發起了異步請求後會阻塞以等待網絡響應,那應該由誰來處理網絡響應呢?蘋果提供了兩種方式,一種是block,提供一個處理響應的block回調。一種是代理,使用代理的話就必須實現NSURLConnectionDelegate這個協議。你只須要在有網絡請求的UIViewController中調用NSURLConnection提供的類方法就能夠了。但若是你的項目中有不止一個UIViewController或者有的UIViewController中都不止一個請求的話,你就須要在每個有網絡請求的UIViewController中這樣寫。這樣寫會有什麼問題呢?首先會形成軟件結構不清晰,沒有剝離出網絡層,其次沒有實現網絡請求統一管理,沒法實現取消全部網絡請求等功能,再有會出現不少重複的代碼,沒有讓公用功能造成模塊,進行復用。固然爲了解決這些問題你也能夠本身實現本身的網絡框架。多線程
使用網絡框架的好處在於能夠將分散在各個視圖控制器中的網絡請求統一塊兒來模塊化造成網絡層,下降與數據層和表現層的耦合。AFNetworking就作了這樣的工做。網絡上已經有不少分析基於NSURLConnection實現的AFNetworking 2.x的源代碼,這裏只簡單說一下其實現整個流程,想要深刻了解的請谷歌或查看其源代碼。首先AFNetworking要解決實現接口統一和全部網絡請求統一管理的問題。NSURLConnection發起有兩種方式發起請求,分別是設置響應block和代理,那採用哪一種方式可以實現網絡請求統一管理呢?block確定不行,由於傳入響應回調block的[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]方法會當即執行。那麼只能使用設置響應代理這種方式了。具體實現是將網絡請求繼承於NSOperation,生產網絡請求,而後再將這個網絡請求加入操做隊列裏,剩下的全部與線程相關的操做都由這個操做隊列去實現。越高級易容的接口就隱藏越多的實現細節,NSOperation隱藏了線程相關的全部細節,使得開發者只需關心構建什麼樣的操做。AFNetworking甚至隱藏了操做,操做隊列的概念,使得開發者只需關心如何設置網絡相關的請求參數,響應回調等,而不用再關心當多個網絡請求如何進行統一管理,這些都已經由AFNetworking內部的操做隊列屬性完成了。那須要爲每一個請求建立一個線程來發起請求嗎?基於NSURLConnection的AFNetworking是隻建立了一條線程來發起全部請求並阻塞以等待響應。併發
從2013年蘋果發佈重構後的加載系統NSURLSession,AFNetworking這個最受歡迎的網絡框架也隨之發佈了基於NSURLSession的實現版本。這篇文章從 NSURLConnection 到 NSURLSession對NSURLSession的使用作了介紹。既然是對NSURLConnection進行的重構,那必定是解決了NSURLConnection存在的一些問題。蘋果的接口以及其簡單的形式呈現給開發者,儘可能把複雜,容易出錯的地方以簡單的接口暴露出來,這使得用戶可以參考文檔很快上手,但這也有一些弊端,就是開發者對其中的原理不是很瞭解。越高級的接口越容易使用,但其隱蔽的實現細節就越多。相信在進行多線程編程的時候,不少開發者遇到過各類各樣的坑,但在iOS平臺上,蘋果推出了GCD,NSperation等一系列接口可讓開發者徹底能夠只關注業務的實現,這些接口內部已經替開發者管理好了線程的建立,銷燬,多線程資源競爭等須要開發者費不少精力的事情,甚至開發者不用對多線程理解透徹都能把多線程用得駕輕就熟。NSURLConnection已經隱藏了線程相關的操做,已經給開發者減輕了不少負擔。但NSURLConnectoin只隱藏了單個網絡請求的線程的相關操做,並無提供接口來解決多個網絡請求時多個線程的管理問題,譬如當有多個網絡請求時是否應該使用線程池來避免不停建立與銷燬線程(這個能夠有NSOperationQueue很好的解決)。而且NSURLConnection不是基於HTTP/2協議的,若使用NSURLConnection發起請求則每次請求都須要通過三次握手過程,可見NSURLConnection確實有不少能夠優化的地方(我只發現這些)。NSURLConnection存在的沒法將多個請求關聯起來的問題已經很好的由AFNetworking解決了,因此推出的NSURLSession能夠說是借鑑了AFNetworking的思想,而且能夠從AFNetworking的源代碼中很容易的看出來。基於NSURLConnection的AFNetworking須要讓網絡請求繼承與NSOperation,而後再將該生成的網絡請求加入操做隊列中,但基於NSURLSessioin的AFNetworking只須要建立一個網絡請求任務就能夠了,緣由在於,NSURLSession內部已經維護了兩個操做隊列,一個是處理session的相關回調,一個是處理響應相關的回調,因此說NSURLSession是借鑑了AFNetworking的繼承於NSOperation和用單線程發起並等待響應的思想(這個會在後面給出證實)。框架
下圖是基於NSURLSession的AFNetworking的UML圖(只爲展現類之間的關聯關係,並無給出每一個類的全部屬性和方法):異步
從該類圖已經可以明白AFNetworking整個的工做流程。模塊化
做者:zongmumask
連接:https://www.jianshu.com/p/8eac5b1975de
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。源碼分析