iOS組件依賴(lài)避免沖突的小技巧分享
問(wèn)題緣由
本文以 YBImageBrowser[1] 組件舉例。
YBImageBrowser 依賴(lài)了 SDWebImage,在使用 CocoaPods 集成到項(xiàng)目中時(shí),可能會(huì)出現(xiàn)一些依賴(lài)沖突的問(wèn)題,最近社區(qū)提了多個(gè) Issues 并且在 Insights -> Traffic -> Popular content 中看到了此類(lèi)問(wèn)題很高的關(guān)注度,所以不得不著手解決。
嚴(yán)格的版本限制
一個(gè)開(kāi)源組件的迭代過(guò)程中,保證上層接口的向下兼容就不錯(cuò)了。為了優(yōu)化性能并且控制內(nèi)存,YBImageBrowser 沒(méi)有直接用其最上層的接口,而是單獨(dú)使用了下載模塊和緩存模塊,SDWebImage 的迭代升級(jí)很容易導(dǎo)致筆者的組件兼容不了,所以之前一直是類(lèi)似這樣依賴(lài)的:
s.dependency 'SDWebImage', '~> 5.0.0'
這樣做的好處是限制足夠小版本范圍,降低 SDWebImage 接口變動(dòng)導(dǎo)致組件代碼錯(cuò)誤的風(fēng)險(xiǎn)。但如果 SDWebImage 升級(jí)到 5.1.0,不管相關(guān) API 是否變動(dòng),CocoaPods 都視為依賴(lài)沖突。
其它組件依賴(lài)了不同版本的 SDWebImage
當(dāng)兩個(gè)組件依賴(lài)了同一個(gè)組件的不同版本,并且依賴(lài)的版本沒(méi)有交集,比如:
A.dependency 'SDWebImage', '~> 4.0.0' B.dependency 'SDWebImage', '~> 5.0.0'
那么 A 和 B 同時(shí)集成進(jìn)項(xiàng)目會(huì)出現(xiàn)依賴(lài)沖突。
解決方案
使用 CocoaPods 集成項(xiàng)目非常便捷,對(duì)于組件使用者來(lái)說(shuō),總是想在任何場(chǎng)景下都能輕易集成,并且能在將來(lái)享受組件的更新優(yōu)化,顯然前面提到的問(wèn)題可能會(huì)影響集成的便捷性。
更模糊的版本限制
很多時(shí)候一個(gè)大版本的組件不會(huì)改動(dòng) API,并且對(duì)于社區(qū)流行的組件我們可以寄一定希望于其做好向下兼容,所以放寬依賴(lài)的版本限制能覆蓋將來(lái)更多的版本(規(guī)則參考:podspec dependency[2]):
s.dependency 'SDWebImage', '>= 5.0.0'
為什么不干脆去掉版本限制呢?
因?yàn)?YBImageBrowser 3.x 是基于 SDWebImage 5.0.0 開(kāi)發(fā)的,筆者可以明確不兼容 5.0.0 之前的版本,所以在 SDWebImage 將來(lái)迭代版本出現(xiàn)相關(guān) API 不兼容之前,這個(gè)限制都是“完美”覆蓋所有版本的。
避免依賴(lài)沖突的暴力方案
當(dāng)有其它組件依賴(lài)了不同版本的 SDWebImage,粗暴的解決方案如下:
• 直接修改其它組件依賴(lài)的 SDWebImage 版本。
• 將 YBImageBrowser 手動(dòng)導(dǎo)入項(xiàng)目,并且修改代碼去適應(yīng)當(dāng)前的 SDWebImage 版本。
• 社區(qū)朋友一個(gè) Issue 中提到的方法:在 ~/.cocoapods/repos 目錄下找到 YBImageBrowser 文件夾,更改對(duì)應(yīng)版本的 podspec.json 文件里對(duì) SDWebImage 的依賴(lài)版本。
顯然,上面的幾種方案不太優(yōu)雅,手動(dòng)導(dǎo)入項(xiàng)目難以享受組件的更新優(yōu)化,修改本地 repo 信息會(huì)因?yàn)?repo 列表的更新而復(fù)位。
避免依賴(lài)沖突的優(yōu)雅方案
出現(xiàn)依賴(lài)沖突是必須要解決的問(wèn)題,其它組件依賴(lài)的版本限制可以視為不變量,解決方案可以從組件的制作方面考慮。
要做到的目標(biāo)是,既滿(mǎn)足部分用戶(hù)快速集成組件,又能讓部分用戶(hù)解決依賴(lài)沖突的前提下保證能享受組件將來(lái)的更新優(yōu)化。
答案就是subspec,以下是 YBImageBrowser.podspec 部分代碼(完整代碼[3]):
s.subspec "Core" do |core| core.source_files = "YBImageBrowser/**/*.{h,m}" core.dependency 'SDWebImage', '>= 5.0.0' end s.subspec "NOSD" do |core| core.source_files = "YBImageBrowser/**/*.{h,m}" core.exclude_files = "YBImageBrowser/WebImageMediator/YBIBDefaultWebImageMediator.{h,m}" end
由此,用戶(hù)可以自由的選擇是否需要依賴(lài) SDWebImage,在 Podfile 里的觀感大致是這樣:
// 依賴(lài) SDWebImage pod 'YBImageBrowser' // 不依賴(lài) SDWebImage pod 'YBImageBrowser/NOSD'
那么在 YBImageBrowser 代碼中應(yīng)該如何區(qū)分是否依賴(lài)了 SDWebImage 并且提供默認(rèn)實(shí)現(xiàn)呢?
第一步是設(shè)計(jì)一個(gè)抽象接口(這個(gè)接口不依賴(lài) SDWebImage):
@protocol YBIBWebImageMediator <NSObject> // Download methode, caching methode, and so on. @end
第二步是在YBImageBrowser.h中定義一個(gè)遵循該接口的屬性:
/// 圖片下載緩存相關(guān)的中介者(賦值可自定義) @property (nonatomic, strong) id<YBIBWebImageMediator> webImageMediator;
第三步是實(shí)現(xiàn)一個(gè)默認(rèn)的中介者(這個(gè)類(lèi)依賴(lài)了 SDWebImage):
@interface YBIBDefaultWebImageMediator : NSObject <YBIBWebImageMediator> @end @implementation YBIBDefaultWebImageMediator //通過(guò) SDWebImage 的 API 實(shí)現(xiàn) <YBIBWebImageMediator> 協(xié)議方法 @end
第四步是在內(nèi)部代碼中通過(guò)條件編譯導(dǎo)入并初始化默認(rèn)中介者:
#if __has_include("YBIBDefaultWebImageMediator.h") #import "YBIBDefaultWebImageMediator.h" #endif ... #if __has_include("YBIBDefaultWebImageMediator.h") _webImageMediator = [YBIBDefaultWebImageMediator new]; #endif
第五步在 YBImageBrowser.podspec 中也可以看到,在不依賴(lài) SDWebImage 的集成方式時(shí)排除了兩個(gè)文件:YBIBDefaultWebImageMediator.{h.m}。
由此便實(shí)現(xiàn)了目標(biāo):
• 用依賴(lài) SDWebImage 的集成方式快速集成。
• 使用不依賴(lài) SDWebImage 的集成方式避免各種情況下的依賴(lài)沖突,但注意這種情況需要自行實(shí)現(xiàn)一個(gè)遵循<YBIBWebImageMediator>協(xié)議的中介者。
以上便是避免依賴(lài)沖突的小技巧,希望讀者朋友能提出更好的建議或意見(jiàn)😁。
參考
[1]https://github.com/indulgeIn/YBImageBrowser
[2]https://guides.cocoapods.org/syntax/podspec.html#dependency
[3]https://github.com/indulgeIn/YBImageBrowser/blob/master/YBImageBrowser.podspec
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)我們的支持。
上一篇:iOS 13適配匯總(推薦)
欄 目:IOS
下一篇:解決iOS13 無(wú)法獲取WiFi名稱(chēng)(SSID)問(wèn)題
本文標(biāo)題:iOS組件依賴(lài)避免沖突的小技巧分享
本文地址:http://mengdiqiu.com.cn/a1/IOS/11870.html
您可能感興趣的文章
- 01-11iOS常用算法之兩個(gè)有序數(shù)組合并(要求時(shí)間復(fù)雜度為0(n))
- 01-11iOS 彈幕功能的實(shí)現(xiàn)思路圖解
- 01-11iOS調(diào)試Block引用對(duì)象無(wú)法被釋放的小技巧分享
- 01-11iOS動(dòng)態(tài)更換Icon的全過(guò)程記錄
- 01-11iOS實(shí)現(xiàn)文本分頁(yè)的方法示例
- 01-11iOS常見(jiàn)宏理解及使用方法
- 01-11iOs遷至WKWebView跨過(guò)的一些坑
- 01-11iOS模擬中獎(jiǎng)名單循環(huán)滾動(dòng)效果
- 01-11Python一鍵查找iOS項(xiàng)目中未使用的圖片、音頻、視頻資源
- 01-11iOS中如何獲取某個(gè)視圖的截圖詳析


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-11UILabel顯示定時(shí)器文本跳動(dòng)問(wèn)題的解決
- 01-11iOS常用算法之兩個(gè)有序數(shù)組合并(要
- 01-11iOS 彈幕功能的實(shí)現(xiàn)思路圖解
- 01-11詳解MacOs免密登錄CentOs操作步驟
- 01-11iOS動(dòng)態(tài)更換Icon的全過(guò)程記錄
- 01-11iOS調(diào)試Block引用對(duì)象無(wú)法被釋放的小技
- 01-11iOS常見(jiàn)宏理解及使用方法
- 01-11iOS實(shí)現(xiàn)文本分頁(yè)的方法示例
- 01-11iOs遷至WKWebView跨過(guò)的一些坑
- 01-11iOS模擬中獎(jiǎng)名單循環(huán)滾動(dòng)效果
隨機(jī)閱讀
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 04-02jquery與jsp,用jquery
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文