首頁 > 軟體

Swift使用SnapKit模仿Kingfisher第三方擴充套件優化

2022-09-14 22:01:52

正文

我們平時用swift寫第三方擴充套件(OC中的分類)時,可能會直接就往擴充套件裡面寫方法,簡單又方便,然而當我們看一些常用你的三方(例如:Kingfisher、SnapKit)等,都會用一個簡單的引數引出(例如:kfsnp),下面來探索一下怎麼用的,然後在總結其優缺點

SnapKit擴充套件方式簡要思考

SnapKit為例,使用如下,發現引入了 snp

var iv = UIImageView();
iv.snp.makeConstraints { make in
}

中間變數 snp 如下所示,ConstraintView是統一不同平臺的重新命名(別名)

public extension ConstraintView {
    var snp: ConstraintViewDSL {
        return ConstraintViewDSL(view: self)
    }
}

其以前版本也是直接將 left 等加上字首 snp_,直接呼叫,而加入字首我想大家一眼就看出來目的了,沒錯避免與其他擴充套件重名,現在也已經改成了引入snp的方式,來間接呼叫,實際邏輯都通過 snp 來呼叫,個人猜測也是借鑑了主流的應用來更新的,呼叫時,至少分類 API 整潔了

優缺點:

  • 1、引入中間變數 snp 之後,首先感覺到的就是,我們的分類在呼叫的時候,明顯沒有那麼多雜亂的方法了(這種方式OC其實也可以借鑑)
  • 2、另外也可以取消了字首,減少了程式碼量,並且當與其他類出現重名的時候,只需要替換 snp 的變數名字即可,不需要替換全部方法,減少了命名阻礙
  • 3、不同三方之間通過引入該引數,讓我們的呼叫模組標識更明顯,功能模組也更清晰,可維護性更強

Kingfisher擴充套件方式簡要思考

Kingfisher為例,使用如下,發現引入了 kf

var iv = UIImageView();
iv.kf.setImage(with: URL(string: "http://www.baidu.com"))

另外其在使用過程中,通過充分利用 swift 特性,比 SnapKit 使用上更優雅高效一些

//宣告一個基礎協定,必須為 AnyObject 型別,可用於後續給基礎類新增協定
public protocol KingfisherCompatible: AnyObject { }
//擴充套件實現該基礎協定,以便於方便讓我們的元件能夠直接通過 .kf 直接呼叫裡面的方法
//此 kf 和 snap 類似,只不過新增了一個泛型,用於不同類之間進行擴充套件限制
extension KingfisherCompatible {
    public var kf: KingfisherWrapper<Self> {
        get { return KingfisherWrapper(self) }
        set { }
    }
}
//通過泛型頂一個一個基礎類,通過該基礎類可以獲取我們被擴充套件的元件
//且通過該基礎類的泛型,可以分別給不同型別新增不同擴充套件方法
public struct KingfisherWrapper<Base> {
    public let base: Base
    public init(_ base: Base) {
        self.base = base
    }
}
//當遵循協定的類為 UIImage 的時候,為其擴充套件方法
extension KingfisherWrapper where Base: KFCrossPlatformImage {
    ...
}
//當遵循協定的類為 KFCrossPlatformImageView 的時候,為其擴充套件方法
extension KingfisherWrapper where Base: KFCrossPlatformImageView {
    ...
}
...
//上面僅僅是定義了一個擴充套件後可以使用的協定,並未應用到我們的基礎元件中
//因此只需要給基礎元件新增擴充套件,遵循我們的協定即可
extension KFCrossPlatformImageView: KingfisherCompatible { }

沒見到名字的View 是為了不同平臺統一名字起的別名,如下所示(打消疑慮專用)

#if os(iOS) || os(tvOS)
    public typealias ConstraintView = UIView
#else
    public typealias ConstraintView = NSView
#endif

優缺點:

  • 1、引入中間變數 kf 之後,首先感覺到的就是,我們的分類在呼叫的時候,明顯沒有那麼多雜亂的方法了(這種方式OC其實也可以借鑑)
  • 2、另外也可以取消了字首,減少了程式碼量,並且當與其他類出現重名的時候,只需要替換 kf 的變數名字即可,不需要替換全部方法,減少了命名阻礙
  • 3、不同三方之間通過引入該引數,讓我們的呼叫模組標識更明顯,功能模組也更清晰,可維護性更強
  • 4、引入協定和泛型,通過協定統一引入同一個中間變數,通過泛型給不同的分類擴充套件出不同的方法,減少無效方法和程式碼等,結構更清晰,某種角度上,其為進階版的擴充套件方式

自行模仿嘗試

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()  
    }
}

這就測試成功了,我們模仿時,就可以參考這個寫

最後

當我們自己為預設元件擴充套件內容時,如果只擴充套件一個類和功能,可以像 snp 一樣,直接引入中間變數擴充套件即可,如果我們的擴充套件了多個分類,而隸屬於一個模組,那麼可以模仿 Kingfisher,讓我們的功能更清晰

以上就是Swift SnapKit模仿Kingfisher第三方擴充套件優化範例的詳細內容,更多關於SnapKit第三方擴充套件的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com