這是在完成對項目3.0升級之后,SnapKit和ReactiveCocoa框架使用方式變化,讓我好奇的去閱讀了一下框架的源碼。學到了這個優(yōu)雅的寫法,覺得很受用。
在swift3.0之前,snapKit和ReactiveCocoa的用法是這樣的:
view.snp_makeConstraints { (make) in
view.snp_top.equalTo(self)
}
let searchStrings = textField.rac_textSignal()
.toSignalProducer()
.map { text in text as! String }
到了swift3.0,兩邊的使用方式變成這樣:
view.snp.makeConstraints { (make) -> Void in
view.snp.top.equalTo(self)
}
let searchStrings = textField.reactive.textValues
可以看出Swift3.0之后,框架不再是直接給對應(yīng)的類擴展方法,而是同意給所有類擴展一個屬性,然后,通過該屬性擴展方法。
具體的是怎么實現(xiàn)的呢,翻看ReactiveCocoa的源碼找到了實現(xiàn)方式,在這里做總結(jié):
1.定義一個協(xié)議 ReactiveExtensionsProvider
2.定義一個帶泛型類型的結(jié)構(gòu)體Reactive<Base> ,該結(jié)構(gòu)體有一個 泛型類型的成員變量,初始化方法,需要傳一個泛型類型的實例。
3.給協(xié)議添加一個Reactive<Base>類型的只讀屬性:reactive,把調(diào)用該寫的對象self作為初始化方法參數(shù)

源碼截圖.png
4.讓NSObject遵守ReactiveExtensionsProvider,就相當于NSObject和他的所有子類都遵守了該協(xié)議,也就有了 reactive屬性

源碼截圖2.png
5.給Reactive寫Extension 用 where判斷Base類型,不同的類型寫不同的方法

源碼截圖3.png
以下是我自己寫的一段Demo代碼
import UIKit
//定義一個協(xié)議
protocol ProviderProtocol {}
//擴展協(xié)議
extension ProviderProtocol{
public var provider: Provider<Self> {
return Provider(self)
}
}
//定義一個結(jié)構(gòu)體
struct Provider<CurrentClass> {
public let currentInstance: CurrentClass
fileprivate init(_ currentInstance: CurrentClass) {
self.currentInstance = currentInstance
}
}
//讓所有的類都遵守協(xié)議
extension NSObject: ProviderProtocol {}
//給不同的類實現(xiàn)不同的方法
extension Provider where CurrentClass: UILabel{
func getTextCharacterCount() -> Int{
return currentInstance.text?.characters.count ?? 0
}
}