首先網(wǎng)絡(luò)層的基礎(chǔ)組件應(yīng)該是AFNetworking 大部分開發(fā)人員都是基于AFNetworking的二次封裝灭翔,比較知名的就是CTNetWork和YTKNetwork魏烫,閱讀完源碼,我認(rèn)為和我們的實際業(yè)務(wù)需求不符合肝箱,我認(rèn)為一個好的網(wǎng)絡(luò)層哄褒,應(yīng)該還有以下特點
- 簡單,易懂的代碼
- 日志輸出
- 緩存應(yīng)該采用lru算法煌张,因為一個開發(fā)人員不清楚用戶具體喜歡哪些內(nèi)容呐赡,只能做重要界面的所有的緩沖,然而用戶可能某時間基于好奇心會點擊APP內(nèi)大部分界面和造成大量緩沖骏融,這種資源浪費是沒必要链嘀,所以個人感覺要清除命中率不高的緩存
- 取消網(wǎng)絡(luò)請求
下面談一下比較知名的CTNetworking和YTKNetwork
在 Casa Taloyum大神 iOS應(yīng)用架構(gòu)談 網(wǎng)絡(luò)層設(shè)計方案 的內(nèi)容文章里面萌狂,談?wù)摰膬纱髥栴}就是block和代理 集約型和離散型的技術(shù)點討論
Casa Taloyum討論了block的在網(wǎng)絡(luò)層使用的時候缺點
block很難追蹤,難以維護
block會延長相關(guān)對象的生命周期
block在離散型場景下不符合使用的規(guī)范
集約型存在的問題
原因1:當(dāng)前請求正在外面飛著的時候怀泊,根據(jù)不同的業(yè)務(wù)需求存在兩種不同的請求起飛策略:一個是取消新發(fā)起的請求茫藏,等待外面飛著的請求著陸。另一個是取消外面飛著的請求霹琼,讓新發(fā)起的請求起飛务傲。集約化的API調(diào)用方式如果要滿足這樣的需求,那么每次要調(diào)用的時候都要多寫一部分判斷和取消的代碼枣申,手段就做不到很干凈售葡。
原因2:便于針對某個API請求來進行AOP。在集約型的API調(diào)用方式下糯而,如果要針對某個API請求的起飛和著陸過程進行AOP天通,這代碼得寫成什么樣。熄驼。像寒。噢,尼瑪這畫面太美別說看了瓜贾,我都不敢想诺祸。
離散型的優(yōu)點
原因3:當(dāng)API請求的著陸點消失時,離散型的API調(diào)用方式能夠更加透明地處理這種情況祭芦。
原因4:離散型的API調(diào)用方式能夠最大程度地給業(yè)務(wù)方提供靈活性筷笨,比如reformer機制就是基于離散型的API調(diào)用方式的。另外龟劲,如果是針對提供翻頁機制的API胃夏,APIManager就能簡單地提供
loadNextPage
方法去加載下一頁,頁碼的管理就不用業(yè)務(wù)方去管理了昌跌。還有就是仰禀,如果要針對業(yè)務(wù)請求參數(shù)進行驗證,比如用戶填寫注冊信息蚕愤,在離散型的APIManager里面實現(xiàn)就會非常輕松答恶。
筆者認(rèn)為“尺有所短寸有所長”每個事物都有他的優(yōu)點和缺點,可能在某一類環(huán)境下A的優(yōu)點多萍诱,某一類環(huán)境下B的有點多了悬嗓,這個問題只是相對的,例如在計算機當(dāng)中裕坊,要么用空間換時間包竹,要么時間換空間,魚和熊掌不可兼的。
block優(yōu)點:
省去了寫代理的很多代碼
2.block 更輕型周瞎,使用更簡單悟狱,能夠直接訪問上下文,這樣類中不需要存儲臨時數(shù)據(jù)堰氓,使用 block 的代碼通常會在同一個地方挤渐,這樣能連貫讀代碼
block缺點:
1.block不夠安全,使用 block 時稍微不注意就形成循環(huán)引用双絮,導(dǎo)致對象釋放不了浴麻。這種循環(huán)引用,一旦出現(xiàn)就比較難檢查出來囤攀。
2.block效率低软免,block出棧需要將使用的數(shù)據(jù)從棧內(nèi)存拷貝到堆內(nèi)存 3.在多個通信事件的時候,block顯得不夠直觀也不易維護焚挠。
delegate優(yōu)點:
1.delegate更安全膏萧, delegate 的方法是分離開的,不會引用上下文蝌衔,不容易循環(huán)引用
2.delegate效率高榛泛,delegate只是保存了一個對象指針
3.在多個通信事件的時候,delegate顯得直觀也易維護噩斟。
delegate缺點:
1.因方法的聲明和實現(xiàn)分離開來曹锨,代碼的連貫性不是很好,沒有 block 好讀
2.很多時候需要存儲一些臨時數(shù)據(jù) ------------
筆者崇尚于更輕型剃允,更簡單沛简,更連貫的代碼,所以筆者在封裝SJNetwork的時候采用的是Block斥废,佛家云:有所舍椒楣,才能有所得。
indulge_in 大神 認(rèn)為CTNetworking 不足:
使用 IOP 方式建立模塊牡肉,化繼承為組合捧灰。獨立
<CTServiceProtocol>
和<CTAPIManagerInterceptor>
等協(xié)議作為集約管理部分,若個別接口需要修改這些公共配置荚板,只能在集約管理模塊來判斷凤壁,顯得有一點繁瑣吩屹。記錄了一個 request 實例的所有 task跪另,在 dealloc 中自動取消掉還未降落的網(wǎng)絡(luò)請求,但是實際上網(wǎng)絡(luò)請求任務(wù)會持有 request煤搜,所以自動取消策略不成立了免绿。
YTKNetwork 不足:
基于多態(tài)的設(shè)計思路,提供了很多供重載的方法擦盾,從設(shè)計來看嘲驾,框架是可以實例化
YTKBaseRequest
子類 直接使用的淌哟,那么直接使用時無法重載這些方法專門定制(個人看來有些地方使用屬性更靈活);并且辽故,當(dāng)一個 reqeust 多次start
發(fā)起請求就會調(diào)用多次這些重載方法徒仓,可能造成多余計算;緩存策略使用一個
YTKBaseRequest
的子類YTKRequest
來做誊垢,雖然這樣看起來比較優(yōu)雅掉弛,父類和子類各司其職,單一職責(zé)喂走,但是緩存策略難免會更改父類的邏輯殃饿,如此就很難不違背開閉原則∮蟪Γ框架的緩存只有一個失效時間控制乎芳,筆者想要拓展時發(fā)現(xiàn)要改的東西太多。同一個 request 實例多次 start 調(diào)用網(wǎng)絡(luò)請求時 (多個網(wǎng)絡(luò)請求并發(fā)情況)帖池,并未作出實際的處理策略奈惑,僅保留最新的
NSURLSessionTask
,而對舊的未結(jié)束的所有NSURLSessionTask
喪失了控制權(quán)睡汹。網(wǎng)絡(luò)請求任務(wù)強持有所有 request 對象携取,在弱網(wǎng)環(huán)境下可能會有大量 request 對象無法釋放,而界面降落點可能不存在了帮孔。
CTNetworking
可讀性比YTKNetwork好
CTJsbridge已經(jīng)可以跟CTNetworking交互雷滋,H5工程師可以很方便地使用基于CTNetworking的網(wǎng)絡(luò)API。
各種錯誤錯誤類型回調(diào)比較全
YTKNetwork
可能是使用了命令模式的原因吧文兢,我覺的YTKNetwork的可讀性不如CTNetworking 個人覺的不管用什么設(shè)計模式晤斩,為的是代碼邏輯更加明確,代碼更加易懂易讀姆坚,如有不認(rèn)同筆者的澳泵,請忽略,畢竟人生百味兼呵,請允許我有百想兔辅,
YTKNetwork和CTNetworking的日志輸出,緩沖击喂,取消網(wǎng)絡(luò)請求维苔,當(dāng)我們使用的時候還的進行網(wǎng)絡(luò)的三次封裝,筆者認(rèn)為懂昂,一個網(wǎng)絡(luò)層設(shè)計介时,應(yīng)該是都封裝進去,然后提供開發(fā)人員調(diào)用就可以了,
SSJNetWork封裝緩沖沸柔,日志循衰,自動網(wǎng)絡(luò)請求。
1.緩存處理
緩存處理配置都在SJNetWorkConfig和SJNetworkRequestConfig類中褐澎,支持以下配置:
- 內(nèi)存/磁盤存儲方式
- 緩存的有效時長
- 根據(jù)請求shouldAllIgnoreCache判斷是否需要緩存
- 以及直接配置 YYCache
- 支持緩沖最大數(shù)量(采用YYCache LRU算法)
- 緩存的版本
2. 自動取消網(wǎng)絡(luò)請求
采用AOP方式hook方式自動取消網(wǎng)絡(luò)請求
請配置 SJNetworkRequestConfigz 中 className 如不傳入?yún)?shù)網(wǎng)絡(luò)請求對應(yīng)vc的className,則自動取消網(wǎng)絡(luò)請求無效
半自動取消網(wǎng)絡(luò)請求根據(jù)的的是会钝,視圖pop和dismiss的時候取消當(dāng)前VC下所有的網(wǎng)絡(luò)請求設(shè)計的
3.采用NetworkEye部分代碼可以監(jiān)控App內(nèi)所有HTTP請求并顯示請求相關(guān)的所有信息,方便App開發(fā)的網(wǎng)絡(luò)調(diào)試
SJNetWorkConfig`變量配置工三,
dubugLogeEnable:請求完成控制臺直接輸出
SQLLogEnable:記錄在sql提高跳轉(zhuǎn)到vc的時候展示
ne_sqlitePassword:log日志數(shù)據(jù)庫密碼
ne_saveRequestMaxCount:保存請求的最大個數(shù)
源碼地址 請點擊這里顽素,歡迎大神指導(dǎo),若考慮不周的地方徒蟆,請大家多提意見