Swift如何創建命名空間

相比于OC時代的完全沒有命名空間,Swift可以通過巧妙的辦法,實現幾乎等同于命名空間的效果。

需求

現在我們希望為UIColor類增加一個擴展方法,根據其自身顏色生成圖像UIImage
在沒有命名空間的時代,可能結果是這樣子的:

let image = UIColor.blue.image

或者為避免與其它框架API同名,可能結果會變成這樣子:

let image = UIColor.blue.jx_image

當然這種風格非常地OC。

那有沒有優雅一點的辦法來代替OC Style?比如能寫成這樣子就好了:

let image = UIColor.blue.jx.image

Swift3繞一下路,也是可以做到的。姑且把中間的.jx叫做命名空間(Namespace),沒錯,抄了一下C#們的叫法。

定義命名空間

具體的做法通過擴展特定的協議來達到目的。
我們需要定義兩個協議,其中一個是固定的寫法:

/// 類型協議
protocol TypeWrapperProtocol {
    associatedtype WrappedType
    var wrappedValue: WrappedType { get }
    init(value: WrappedType)
}

struct NamespaceWrapper<T>: TypeWrapperProtocol {
    let wrappedValue: T
    init(value: T) {
        self.wrappedValue = value
    }
}

另一個協議基本上也是固定的寫法,只是根據我們的需要,更改其內的命名空間名字即可。
比如我需要一個名為jx的命名空間,就可以這樣寫:

/// 命名空間協議
protocol NamespaceWrappable {
    associatedtype WrapperType
    var jx: WrapperType { get }
    static var jx: WrapperType.Type { get }
}

extension NamespaceWrappable {
    var jx: NamespaceWrapper<Self> {
        return NamespaceWrapper(value: self)
    }
    static var jx: NamespaceWrapper<Self>.Type {
        return NamespaceWrapper.self
    }
}

需要什么樣的命名空間,就把其中的jx改成你希望的名字。

使用命名空間

實際上我們需要擴展的類不是UIColor,而是協議。
這里分兩步,第一步是讓需要擴展的類遵循協議NamespaceWrappable

extension UIColor: NamespaceWrappable {}

第二步是擴展協議TypeWrapperProtocol

extension TypeWrapperProtocol where WrappedType == UIColor {
    /// 用自身顏色生成UIImage
    var image: UIImage? {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(wrappedValue.cgColor)
        context?.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        return image
    }
}

在擴展的方法中,self代表的是協議,而不是目標擴展類。那要用到self怎么辦?用wrappedValue吧,它就是我們的目標類/實例。

驗證

現在可以愉快地玩耍了:

let image = UIColor.blue.jx.image

使用了命名空間后,還有一個優點就是可以利用Xcode的代碼補全。

Xcode代碼補全
Xcode代碼補全

相比在打出.im后Xcode會彈出一大堆匹配到im兩字母的方法,使用了命名空間后,點出.jx.時,Xcode就只會提示此命名空間內的方法/屬性。特別是StringUIView這種有巨量方法的類,只要打出命名空間就可以快速過濾不需要的方法。

下載Demo

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容