首先網絡層的基礎組件應該是AFNetworking 大部分開發人員都是基於AFNetworking的二次封裝,比較知名的就是CTNetWork和YTKNetwork,閱讀完源碼,我認爲和咱們的實際業務需求不符合,我認爲一個好的網絡層,應該還有如下特色html
下面談一下比較知名的CTNetworking和YTKNetworkios
在 Casa Taloyum大神 iOS應用架構談 網絡層設計方案 的內容文章裏面,談論的兩大問題就是block和代理 集約型和離散型的技術點討論git
Casa Taloyum討論了block的在網絡層使用的時候缺點
- block很難追蹤,難以維護
- block會延長相關對象的生命週期
集約型存在的問題
- block在離散型場景下不符合使用的規範
- 緣由1:當前請求正在外面飛着的時候,根據不一樣的業務需求存在兩種不一樣的請求起飛策略:一個是取消新發起的請求,等待外面飛着的請求着陸。另外一個是取消外面飛着的請求,讓新發起的請求起飛。集約化的API調用方式若是要知足這樣的需求,那麼每次要調用的時候都要多寫一部分判斷和取消的代碼,手段就作不到很乾淨。
- 緣由2:便於針對某個API請求來進行AOP。在集約型的API調用方式下,若是要針對某個API請求的起飛和着陸過程進行AOP,這代碼得寫成什麼樣。。。噢,尼瑪這畫面太美別說看了,我都不敢想。
- 離散型的優勢
- 緣由3:當API請求的着陸點消失時,離散型的API調用方式可以更加透明地處理這種狀況。
- 緣由4:離散型的API調用方式可以最大程度地給業務方提供靈活性,好比reformer機制就是基於離散型的API調用方式的。另外,若是是針對提供翻頁機制的API,APIManager就能簡單地提供
loadNextPage
方法去加載下一頁,頁碼的管理就不用業務方去管理了。還有就是,若是要針對業務請求參數進行驗證,好比用戶填寫註冊信息,在離散型的APIManager裏面實現就會很是輕鬆。
筆者認爲「尺有所短寸有所長」每一個事物都有他的優勢和缺點,可能在某一類環境下A的優勢多,某一類環境下B的有點多了,這個問題只是相對的,例如在計算機當中,要麼用空間換時間,要麼時間換空間,魚和熊掌不可兼的。github
block優勢:算法
- 省去了寫代理的不少代碼
- 2.block 更輕型,使用更簡單,可以直接訪問上下文,這樣類中不須要存儲臨時數據,使用 block 的代碼一般會在同一個地方,這樣能連貫讀代碼
block缺點: sql
- 1.block不夠安全,使用 block 時稍微不注意就造成循環引用,致使對象釋放不了。這種循環引用,一旦出現就比較難檢查出來。
- 2.block效率低,block出棧須要將使用的數據從棧內存拷貝到堆內存 3.在多個通訊事件的時候,block顯得不夠直觀也不易維護。
delegate優勢:數據庫
1.delegate更安全, delegate 的方法是分離開的,不會引用上下文,不容易循環引用
2.delegate效率高,delegate只是保存了一個對象指針 設計模式
3.在多個通訊事件的時候,delegate顯得直觀也易維護。delegate缺點: 緩存
- 1.因方法的聲明和實現分離開來,代碼的連貫性不是很好,沒有 block 好讀
- 2.不少時候須要存儲一些臨時數據 ------------
筆者崇尚於更輕型,更簡單,更連貫的代碼,因此筆者在封裝SJNetwork的時候採用的是Block,佛家雲:有所舍,纔能有所得。安全
indulge_in 大神 認爲CTNetworking 不足:
- 使用 IOP 方式創建模塊,化繼承爲組合。獨立
<CTServiceProtocol>
和<CTAPIManagerInterceptor>
等協議做爲集約管理部分,若個別接口須要修改這些公共配置,只能在集約管理模塊來判斷,顯得有一點繁瑣。- 記錄了一個 request 實例的全部 task,在 dealloc 中自動取消掉還未降落的網絡請求,可是實際上網絡請求任務會持有 request,因此自動取消策略不成立了。
YTKNetwork 不足:
- 基於多態的設計思路,提供了不少供重載的方法,從設計來看,框架是能夠實例化
YTKBaseRequest
子類 直接使用的,那麼直接使用時沒法重載這些方法專門定製(我的看來有些地方使用屬性更靈活);而且,當一個 reqeust 屢次start
發起請求就會調用屢次這些重載方法,可能形成多餘計算;- 緩存策略使用一個
YTKBaseRequest
的子類YTKRequest
來作,雖然這樣看起來比較優雅,父類和子類各司其職,單一職責,可是緩存策略不免會更改父類的邏輯,如此就很難不違背開閉原則。框架的緩存只有一個失效時間控制,筆者想要拓展時發現要改的東西太多。- 同一個 request 實例屢次 start 調用網絡請求時 (多個網絡請求併發狀況),並未做出實際的處理策略,僅保留最新的
NSURLSessionTask
,而對舊的未結束的全部NSURLSessionTask
喪失了控制權。- 網絡請求任務強持有全部 request 對象,在弱網環境下可能會有大量 request 對象沒法釋放,而界面降落點可能不存在了。
可讀性比YTKNetwork好
CTJsbridge已經能夠跟CTNetworking交互,H5工程師能夠很方便地使用基於CTNetworking的網絡API。
各類錯誤錯誤類型回調比較全
YTKNetwork
多是使用了命令模式的緣由吧,我覺的YTKNetwork的可讀性不如CTNetworking 我的覺的無論用什麼設計模式,爲的是代碼邏輯更加明確,代碼更加易懂易讀,若有不認同筆者的,請忽略,畢竟人生百味,請容許我有百想,
YTKNetwork和CTNetworking的日誌輸出,緩衝,取消網絡請求,當咱們使用的時候還的進行網絡的三次封裝,筆者認爲,一個網絡層設計,應該是都封裝進去,而後提供開發人員調用就能夠了,
1.緩存處理
緩存處理配置都在SJNetWorkConfig和SJNetworkRequestConfig類中,支持如下配置:
2. 自動取消網絡請求
採用AOP hook方式自動取消網絡請求
swizzling_exchangeMethod([self class],@selector(popViewControllerAnimated:), @selector(ssj_popViewControllerAnimated:));
swizzling_exchangeMethod([self class],@selector(popToRootViewControllerAnimated:), @selector(ssj_popToRootViewControllerAnimated:));
swizzling_exchangeMethod([self class],@selector(popToViewController:animated:), @selector(ssj_popToViewController:animated:));
swizzling_exchangeMethod([self class],@selector(dismissViewControllerAnimated:completion:), @selector(ssj_dismissViewControllerAnimated:completion:));
複製代碼
請配置 SJNetworkRequestConfigz 中 className 如不傳入參數網絡請求對應vc的className,則自動取消網絡請求無效
自動取消網絡請求根據的的是,視圖pop和dismiss的時候取消當前VC下全部的網絡請求設計的
3.日誌輸出,採用NetworkEye部分代碼能夠監控App內全部HTTP請求並顯示請求相關的全部信息,方便App開發的網絡調試
SJNetWorkConfig`變量配置,
dubugLogeEnable:請求完成控制檯直接輸出
SQLLogEnable:記錄在sql提升跳轉到vc的時候展現
ne_sqlitePassword:log日誌數據庫密碼
ne_saveRequestMaxCount:保存請求的最大個數
源碼地址 請點擊這裏,歡迎大神指導,若考慮不周的地方,請你們多提意見