談?wù)?iOS 網(wǎng)絡(luò)層設(shè)計(jì)(SSJNetWork封裝緩沖,log日志,自動網(wǎng)絡(luò)請求)

首先網(wǎng)絡(luò)層的基礎(chǔ)組件應(yīng)該是AFNetworking 大部分開發(fā)人員都是基于AFNetworking的二次封裝,比較知名的就是CTNetWork和YTKNetwork,閱讀完源碼,我認(rèn)為和我們的實(shí)際業(yè)務(wù)需求不符合,我認(rèn)為一個好的網(wǎng)絡(luò)層,應(yīng)該還有以下特點(diǎn)

  1. 簡單,易懂的代碼
  2. 日志輸出
  3. 緩存應(yīng)該采用lru算法,因?yàn)橐粋€開發(fā)人員不清楚用戶具體喜歡哪些內(nèi)容,只能做重要界面的所有的緩沖,然而用戶可能某時間基于好奇心會點(diǎn)擊APP內(nèi)大部分界面和造成大量緩沖,這種資源浪費(fèi)是沒必要,所以個人感覺要清除命中率不高的緩存
  4. 取消網(wǎng)絡(luò)請求

下面談一下比較知名的CTNetworking和YTKNetwork

Casa Taloyum大神 iOS應(yīng)用架構(gòu)談 網(wǎng)絡(luò)層設(shè)計(jì)方案 的內(nèi)容文章里面,談?wù)摰膬纱髥栴}就是block和代理 集約型和離散型的技術(shù)點(diǎn)討論

Casa Taloyum討論了block的在網(wǎng)絡(luò)層使用的時候缺點(diǎn)

  • block很難追蹤,難以維護(hù)

  • block會延長相關(guān)對象的生命周期

  • block在離散型場景下不符合使用的規(guī)范

集約型存在的問題

  • 原因1:當(dāng)前請求正在外面飛著的時候,根據(jù)不同的業(yè)務(wù)需求存在兩種不同的請求起飛策略:一個是取消新發(fā)起的請求,等待外面飛著的請求著陸。另一個是取消外面飛著的請求,讓新發(fā)起的請求起飛。集約化的API調(diào)用方式如果要滿足這樣的需求,那么每次要調(diào)用的時候都要多寫一部分判斷和取消的代碼,手段就做不到很干凈。

  • 原因2:便于針對某個API請求來進(jìn)行AOP。在集約型的API調(diào)用方式下,如果要針對某個API請求的起飛和著陸過程進(jìn)行AOP,這代碼得寫成什么樣。。。噢,尼瑪這畫面太美別說看了,我都不敢想。

  • 離散型的優(yōu)點(diǎn)

  • 原因3:當(dāng)API請求的著陸點(diǎn)消失時,離散型的API調(diào)用方式能夠更加透明地處理這種情況。

  • 原因4:離散型的API調(diào)用方式能夠最大程度地給業(yè)務(wù)方提供靈活性,比如reformer機(jī)制就是基于離散型的API調(diào)用方式的。另外,如果是針對提供翻頁機(jī)制的API,APIManager就能簡單地提供loadNextPage方法去加載下一頁,頁碼的管理就不用業(yè)務(wù)方去管理了。還有就是,如果要針對業(yè)務(wù)請求參數(shù)進(jìn)行驗(yàn)證,比如用戶填寫注冊信息,在離散型的APIManager里面實(shí)現(xiàn)就會非常輕松。

筆者認(rèn)為“尺有所短寸有所長”每個事物都有他的優(yōu)點(diǎn)和缺點(diǎn),可能在某一類環(huán)境下A的優(yōu)點(diǎn)多,某一類環(huán)境下B的有點(diǎn)多了,這個問題只是相對的,例如在計(jì)算機(jī)當(dāng)中,要么用空間換時間,要么時間換空間,魚和熊掌不可兼的。

block優(yōu)點(diǎn):

  • 省去了寫代理的很多代碼

  • 2.block 更輕型,使用更簡單,能夠直接訪問上下文,這樣類中不需要存儲臨時數(shù)據(jù),使用 block 的代碼通常會在同一個地方,這樣能連貫讀代碼

block缺點(diǎn):

  • 1.block不夠安全,使用 block 時稍微不注意就形成循環(huán)引用,導(dǎo)致對象釋放不了。這種循環(huán)引用,一旦出現(xiàn)就比較難檢查出來。

  • 2.block效率低,block出棧需要將使用的數(shù)據(jù)從棧內(nèi)存拷貝到堆內(nèi)存 3.在多個通信事件的時候,block顯得不夠直觀也不易維護(hù)。

delegate優(yōu)點(diǎn):

1.delegate更安全, delegate 的方法是分離開的,不會引用上下文,不容易循環(huán)引用

2.delegate效率高,delegate只是保存了一個對象指針

3.在多個通信事件的時候,delegate顯得直觀也易維護(hù)。

delegate缺點(diǎn):

  • 1.因方法的聲明和實(shí)現(xiàn)分離開來,代碼的連貫性不是很好,沒有 block 好讀

  • 2.很多時候需要存儲一些臨時數(shù)據(jù) ------------

筆者崇尚于更輕型,更簡單,更連貫的代碼,所以筆者在封裝SJNetwork的時候采用的是Block,佛家云:有所舍,才能有所得。

indulge_in 大神 認(rèn)為CTNetworking 不足:

  • 使用 IOP 方式建立模塊,化繼承為組合。獨(dú)立<CTServiceProtocol><CTAPIManagerInterceptor>等協(xié)議作為集約管理部分,若個別接口需要修改這些公共配置,只能在集約管理模塊來判斷,顯得有一點(diǎn)繁瑣。

  • 記錄了一個 request 實(shí)例的所有 task,在 dealloc 中自動取消掉還未降落的網(wǎng)絡(luò)請求,但是實(shí)際上網(wǎng)絡(luò)請求任務(wù)會持有 request,所以自動取消策略不成立了。

YTKNetwork 不足:

  • 基于多態(tài)的設(shè)計(jì)思路,提供了很多供重載的方法,從設(shè)計(jì)來看,框架是可以實(shí)例化YTKBaseRequest子類 直接使用的,那么直接使用時無法重載這些方法專門定制(個人看來有些地方使用屬性更靈活);并且,當(dāng)一個 reqeust 多次start發(fā)起請求就會調(diào)用多次這些重載方法,可能造成多余計(jì)算;

  • 緩存策略使用一個YTKBaseRequest的子類YTKRequest來做,雖然這樣看起來比較優(yōu)雅,父類和子類各司其職,單一職責(zé),但是緩存策略難免會更改父類的邏輯,如此就很難不違背開閉原則??蚣艿木彺嬷挥幸粋€失效時間控制,筆者想要拓展時發(fā)現(xiàn)要改的東西太多。

  • 同一個 request 實(shí)例多次 start 調(diào)用網(wǎng)絡(luò)請求時 (多個網(wǎng)絡(luò)請求并發(fā)情況),并未作出實(shí)際的處理策略,僅保留最新的NSURLSessionTask,而對舊的未結(jié)束的所有NSURLSessionTask喪失了控制權(quán)。

  • 網(wǎng)絡(luò)請求任務(wù)強(qiáng)持有所有 request 對象,在弱網(wǎng)環(huán)境下可能會有大量 request 對象無法釋放,而界面降落點(diǎn)可能不存在了。

CTNetworking

可讀性比YTKNetwork好

CTJsbridge已經(jīng)可以跟CTNetworking交互,H5工程師可以很方便地使用基于CTNetworking的網(wǎng)絡(luò)API。

各種錯誤錯誤類型回調(diào)比較全

YTKNetwork

可能是使用了命令模式的原因吧,我覺的YTKNetwork的可讀性不如CTNetworking 個人覺的不管用什么設(shè)計(jì)模式,為的是代碼邏輯更加明確,代碼更加易懂易讀,如有不認(rèn)同筆者的,請忽略,畢竟人生百味,請?jiān)试S我有百想,

YTKNetwork和CTNetworking的日志輸出,緩沖,取消網(wǎng)絡(luò)請求,當(dāng)我們使用的時候還的進(jìn)行網(wǎng)絡(luò)的三次封裝,筆者認(rèn)為,一個網(wǎng)絡(luò)層設(shè)計(jì),應(yīng)該是都封裝進(jìn)去,然后提供開發(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è)計(jì)的

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ù)

源碼地址 請點(diǎn)擊這里,歡迎大神指導(dǎo),若考慮不周的地方,請大家多提意見

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

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