Swift工具類命名空間隔離

Swift工具類命名空間隔離

前言

OC 中一直一來就有一個(gè)很讓人頭疼的問題就是方法名或者類名重復(fù)的問題,特別是在使用第三方 SDK 中包含了一個(gè)與自己在項(xiàng)目中與用到的同一個(gè)第三方框架,這是一個(gè)很頭疼的問題.

遇到這種情況,你只有兩個(gè)選擇:

1.換一個(gè)相同功能的第三方框架

2.把這個(gè)第三方框架中的方法名和類名全改了

所以,一直一來在 OC 的第三方框架中,都加了前綴,如 AFNetworking, MJRefresh, YYModel.即使是在我們自己寫的類中,也會加上前綴

但是加上前綴也只是減小了重復(fù)的可能性,并不能完全的不會重復(fù)

然后,蘋果發(fā)布了 Swift,像許多優(yōu)秀的編程語言一樣,在 Swift 中避開了 OC 中的尷尬情況,采用用命名空間的概念.

然而在 Swift 中的命名空間是基于一個(gè) Module 的,也就是一個(gè) Module 是一個(gè)命名空間.這也就是為什么現(xiàn)在的 Snapkit 使用的時(shí)候會view.snp.xxxx,Kingfisher 使用的時(shí)候要用imageView.kf.xxxx.

但是在我們自己平時(shí)在寫一些工具類或者 Foundation框架的類的擴(kuò)展的時(shí)候,有可能會有一些方法與系統(tǒng)或者別人寫的方法重名,這就很尷尬了!

這個(gè)前言好像有點(diǎn)長了??


類型嵌套

不過好在 SWift 為我們提供了類型嵌套的方法,我們可以在一個(gè)類型(可以是類,結(jié)構(gòu)體,枚舉類型)里面去定義別一個(gè)類型,從而達(dá)到隔離內(nèi)部類型的方法,可以參考喵神的文章

struct MyOuterClass1 {
    class MyClass {
        class func hello() {
            print("hello from MyClassContainer1")
        }
    }
}

struct MyOuterClass2 {
    class MyClass {
        class func hello() {
            print("hello from MyClassContainer2")
        }
    }
}

使用時(shí):

MyOuterClass1.MyClass.hello()
MyOuterClass2.MyClass.hello()

<a name="protocol"></a>為擴(kuò)展類型添加協(xié)議一致性

閱讀 SnapKit 和 Kingfisher 的代碼后,你會發(fā)現(xiàn)它們并沒有使用類型嵌套,而是是用了一個(gè)很巧妙的方法來實(shí)現(xiàn)的: 自定義一個(gè)類并且提供一個(gè)協(xié)議來完成

下面我們看一下如何隔離我們的工具類:

1.先定義一個(gè)泛型工具類TTAUtils<Base>,并提供一個(gè)對應(yīng)泛型的屬性和一個(gè)初始化方法

2.定義一個(gè)泛型協(xié)議,在協(xié)議中定義一個(gè)工具類只讀的一個(gè)實(shí)例屬性和一個(gè)類型屬性,用來調(diào)用你工具類的方法,在協(xié)議擴(kuò)展中分類給定兩個(gè)默認(rèn)實(shí)現(xiàn),分別返回一個(gè) TTAUtils 的實(shí)例和 TTAUtils 的類型

3.然后給你要擴(kuò)展的類型在擴(kuò)展中添加協(xié)議一致性

Show you the code!

public final class TTAUtils<Base> {
    
    public let base: Base
    public init(_ base: Base) {
        self.base = base
    }
}

public protocol TTAUtilsCompatiable {
    
    associatedtype CompatiableType
    var tta: CompatiableType { get }
    static var ttaClass: CompatiableType.Type { get }
}

public extension TTAUtilsCompatiable {
    
    public var tta: TTAUtils<Self> {
        return TTAUtils(self)
    }
    public static var ttaClass: TTAUtils<Self>.Type {
        return TTAUtils<Self>.self
    }
}

extension NSObject: TTAUtilsCompatiable { }

上面的準(zhǔn)備工作做好了,下面我們來為類型添加協(xié)議一致性

/// 為 TTAUtils 類添加擴(kuò)展方法
extension TTAUtils where Base: UIImageView {
    
    public func setImageWithURL(url: URL?, placeholderImage: UIImage?) {
        print(url ?? "not a url")
    }
}

如果添加的類型是結(jié)構(gòu)體類型,需要一些額外的工作:

/// 定義一個(gè)結(jié)構(gòu)體類型
public struct StringProxy {
    fileprivate let base: StringTTAUtilsCompatiable
    init(proxy: String) {
        base = proxy
    }
}
/// 為 String 結(jié)構(gòu)體添加協(xié)議一致性,并實(shí)現(xiàn)對應(yīng)的屬性 `getter`
extension String: TTAUtilsCompatiable {
    public var tta: StringProxy {
        return StringProxy(proxy: self)
    }
}

/// 為自定義結(jié)構(gòu)體添加擴(kuò)展方法
extension StringProxy {
    public func printAString() {
        print(base)
    }
}

使用:

/// 類類型
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
imageView.backgroundColor = .blue
imageView.center = aView.center
aView.addSubview(imageView)
imageView.tta.setImageWithURL(url: URL(string: "Here is a image url string"), placeholderImage: nil)

/// 結(jié)構(gòu)體類型
let string = "Hello world"
string.tta.printAString()

總結(jié)

以上兩種方法,我個(gè)人更推薦第二種方法(為擴(kuò)展類型添加協(xié)議一致性)

因?yàn)檫@種方法,可以讓你:

1.很靈活的擴(kuò)展任何想要擴(kuò)展的類型

2.調(diào)用起來可以與主流框架(SnapKit, Kingfisher) 類似,又可以與我們習(xí)慣的 OC 寫法想對應(yīng)!

Where is the code?

Here is the Code

來自: https://www.tobyotenma.top/blog/?p=92

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,046評論 4 61
  • 文|趙曉璃 寫在前面的話: 不知你有沒有這樣的困惑,在職場如戰(zhàn)場的嚴(yán)峻形勢下,你想溝通卻苦于沒有方法,怕說錯(cuò)了惹麻...
    趙曉璃閱讀 2,404評論 14 81
  • 隨時(shí)間的磨礪 總要經(jīng)歷孤單! 總要經(jīng)歷難過! 總要經(jīng)歷失??! 總要經(jīng)歷脆弱! 總要經(jīng)歷拼搏! 總要經(jīng)歷磨難! 學(xué)會...
    紫竹_徐芳閱讀 355評論 0 0

友情鏈接更多精彩內(nèi)容