最近在看一些Swift開源庫的時候胞谭,發(fā)現(xiàn)了一些優(yōu)秀的開源庫都使用了命名空間鼓拧,例如Kingfisher這個開源庫中,就針對UIImage,UIImageView,UIButton做了命名空間的擴展。通過logoImageView.kf.setImage(url)
這種方式能夠很好地避免擴展的命名沖突骇钦,而且相對 logoImageView.kf_setImage(url)
這種通過前綴避免命名沖突的方式,具有更好的可讀性西疤,而且更Swifty化币绩。
實現(xiàn)原理
主要通過三點來實現(xiàn):
- 泛型類
- 泛型協(xié)議
- 協(xié)議擴展
分析
這是演示代碼:
// 定義泛型類
public final class YKKit<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
// 定義泛型協(xié)議
public protocol YKKitCompatible {
associatedtype CompatibleType
var yk: CompatibleType { get }
}
// 協(xié)議的擴展
public extension YKKitCompatible {
public var yk: YKKit<Self>{
get { return YKKit(self) }
}
}
// 實現(xiàn)命名空間yk
extension String: YKKitCompatible {}
// String命名空間yk中的函數(shù)
extension YKKit where Base == String {
// MARK: - Localized
/// 國際化值
public var localized: String {
return NSLocalizedString(base, comment: "")
}
}
// 使用
let string = "abcd".yk.localized
簡單解析一下實現(xiàn)代碼,主要用到了protocol和generic來實現(xiàn)瘸羡,而且實現(xiàn)有點繞沫换。
首先定義一個泛型類YKKit,使用泛型Base
然后定義支持泛型的協(xié)議YKKitCompatible最铁,并通過協(xié)議擴展提供協(xié)議的默認實現(xiàn)讯赏,返回實現(xiàn)泛型類YKKit的對象自身。
然后對需要實現(xiàn)命名空間的類提供YKKitCompatible協(xié)議擴展冷尉,并實現(xiàn)相關命名空間的對象方法(主要是擴展新的方法漱挎,如代碼中的localized方法)。
整個過程比較繞雀哨,主要還是通過協(xié)議來劃分命名空間磕谅,只有遵循協(xié)議的類才擁有該命名空間,這可能需要進一步理解雾棺。