Swift使用SnapKit模仿Kingfisher第三方擴(kuò)展優(yōu)化
正文
我們平時用swift寫第三方擴(kuò)展(OC中的分類)時,可能會直接就往擴(kuò)展里面寫方法,簡單又方便,然而當(dāng)我們看一些常用你的三方(例如:Kingfisher、SnapKit)等,都會用一個簡單的參數(shù)引出(例如:kf、snp),下面來探索一下怎么用的,然后在總結(jié)其優(yōu)缺點
SnapKit擴(kuò)展方式簡要思考
以 SnapKit為例,使用如下,發(fā)現(xiàn)引入了 snp
var iv = UIImageView();
iv.snp.makeConstraints { make in
}
中間變量 snp 如下所示,ConstraintView是統(tǒng)一不同平臺的重命名(別名)
public extension ConstraintView {
var snp: ConstraintViewDSL {
return ConstraintViewDSL(view: self)
}
}
其以前版本也是直接將 left 等加上前綴 snp_,直接調(diào)用,而加入前綴我想大家一眼就看出來目的了,沒錯避免與其他擴(kuò)展重名,現(xiàn)在也已經(jīng)改成了引入snp的方式,來間接調(diào)用,實際邏輯都通過 snp 來調(diào)用,個人猜測也是借鑒了主流的應(yīng)用來更新的,調(diào)用時,至少分類 API 整潔了
優(yōu)缺點:
- 1、引入中間變量
snp之后,首先感覺到的就是,我們的分類在調(diào)用的時候,明顯沒有那么多雜亂的方法了(這種方式OC其實也可以借鑒) - 2、另外也可以取消了
前綴,減少了代碼量,并且當(dāng)與其他類出現(xiàn)重名的時候,只需要替換snp的變量名字即可,不需要替換全部方法,減少了命名阻礙 - 3、不同三方之間通過引入該參數(shù),讓我們的調(diào)用模塊標(biāo)識更明顯,功能模塊也更清晰,可維護(hù)性更強
Kingfisher擴(kuò)展方式簡要思考
以 Kingfisher為例,使用如下,發(fā)現(xiàn)引入了 kf
var iv = UIImageView(); iv.kf.setImage(with: URL(string: "http://www.baidu.com"))
另外其在使用過程中,通過充分利用 swift 特性,比 SnapKit 使用上更優(yōu)雅高效一些
//聲明一個基礎(chǔ)協(xié)議,必須為 AnyObject 類型,可用于后續(xù)給基礎(chǔ)類添加協(xié)議
public protocol KingfisherCompatible: AnyObject { }
//擴(kuò)展實現(xiàn)該基礎(chǔ)協(xié)議,以便于方便讓我們的組件能夠直接通過 .kf 直接調(diào)用里面的方法
//此 kf 和 snap 類似,只不過添加了一個泛型,用于不同類之間進(jìn)行擴(kuò)展限制
extension KingfisherCompatible {
public var kf: KingfisherWrapper<Self> {
get { return KingfisherWrapper(self) }
set { }
}
}
//通過泛型頂一個一個基礎(chǔ)類,通過該基礎(chǔ)類可以獲取我們被擴(kuò)展的組件
//且通過該基礎(chǔ)類的泛型,可以分別給不同類型添加不同擴(kuò)展方法
public struct KingfisherWrapper<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
//當(dāng)遵循協(xié)議的類為 UIImage 的時候,為其擴(kuò)展方法
extension KingfisherWrapper where Base: KFCrossPlatformImage {
...
}
//當(dāng)遵循協(xié)議的類為 KFCrossPlatformImageView 的時候,為其擴(kuò)展方法
extension KingfisherWrapper where Base: KFCrossPlatformImageView {
...
}
...
//上面僅僅是定義了一個擴(kuò)展后可以使用的協(xié)議,并未應(yīng)用到我們的基礎(chǔ)組件中
//因此只需要給基礎(chǔ)組件添加擴(kuò)展,遵循我們的協(xié)議即可
extension KFCrossPlatformImageView: KingfisherCompatible { }
沒見到名字的View 是為了不同平臺統(tǒng)一名字起的別名,如下所示(打消疑慮專用)
#if os(iOS) || os(tvOS)
public typealias ConstraintView = UIView
#else
public typealias ConstraintView = NSView
#endif
優(yōu)缺點:
- 1、引入中間變量
kf之后,首先感覺到的就是,我們的分類在調(diào)用的時候,明顯沒有那么多雜亂的方法了(這種方式OC其實也可以借鑒) - 2、另外也可以取消了前綴,減少了代碼量,并且當(dāng)與其他類出現(xiàn)重名的時候,只需要替換
kf的變量名字即可,不需要替換全部方法,減少了命名阻礙 - 3、不同三方之間通過引入該參數(shù),讓我們的調(diào)用模塊標(biāo)識更明顯,功能模塊也更清晰,可維護(hù)性更強
- 4、引入?yún)f(xié)議和泛型,通過協(xié)議統(tǒng)一引入同一個中間變量,通過泛型給不同的分類擴(kuò)展出不同的方法,減少無效方法和代碼等,結(jié)構(gòu)更清晰,某種角度上,其為進(jìn)階版的擴(kuò)展方式
自行模仿嘗試
public protocol MarshalTest: AnyObject {}
struct Wrapper<T> {
public let base: T
init(_ base: T) {
self.base = base
}
}
extension MarshalTest {
var ml: Wrapper<Self> {
get { Wrapper(self) }
set { }
}
}
extension UIImageView : MarshalTest {}
extension Wrapper where T: UIImageView {
func setImg() {
}
}
extension Wrapper where T: UIView {
func setBkg() {
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
var iv2 = UIImageView()
iv2.ml.setImg()
}
}
這就測試成功了,我們模仿時,就可以參考這個寫
最后
當(dāng)我們自己為默認(rèn)組件擴(kuò)展內(nèi)容時,如果只擴(kuò)展一個類和功能,可以像 snp 一樣,直接引入中間變量擴(kuò)展即可,如果我們的擴(kuò)展了多個分類,而隸屬于一個模塊,那么可以模仿 Kingfisher,讓我們的功能更清晰
以上就是Swift SnapKit模仿Kingfisher第三方擴(kuò)展優(yōu)化示例的詳細(xì)內(nèi)容,更多關(guān)于SnapKit第三方擴(kuò)展的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SwiftUI中@ViewBuilder的相關(guān)知識點解密
IOS開發(fā)目前最主流的框架當(dāng)屬SwiftUI了,這篇文章主要給大家介紹了關(guān)于SwiftUI中@ViewBuilder的一些相關(guān)知識點,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07
Swift如何在應(yīng)用中添加圖標(biāo)更換功能的方法
本篇文章主要介紹了Swift如何在應(yīng)用中添加圖標(biāo)更換功能的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02
Swift教程之基礎(chǔ)數(shù)據(jù)類型詳解
這篇文章主要介紹了Swift教程之基礎(chǔ)數(shù)據(jù)類型詳解,本文詳細(xì)講解了Swift中的基本數(shù)據(jù)類型和基本語法,例如常量和變量、注釋、分號、整數(shù)、數(shù)值類型轉(zhuǎn)換等內(nèi)容,需要的朋友可以參考下2015-01-01

