Swift工具類命名空間隔離

Swift工具類命名空間隔離

前言

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

遇到這種情況,你只有兩個選擇:

1.換一個相同功能的第三方框架

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

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

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

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

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

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

這個前言好像有點長了??


類型嵌套

不過好在 SWift 為我們提供了類型嵌套的方法,我們可以在一個類型(可以是類,結(jié)構(gòu)體,枚舉類型)里面去定義別一個類型,從而達(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")
        }
    }
}

使用時:

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

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

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

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

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

2.定義一個泛型協(xié)議,在協(xié)議中定義一個工具類只讀的一個實例屬性和一個類型屬性,用來調(diào)用你工具類的方法,在協(xié)議擴(kuò)展中分類給定兩個默認(rèn)實現(xiàn),分別返回一個 TTAUtils 的實例和 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)體類型,需要一些額外的工作:

/// 定義一個結(jié)構(gòu)體類型
public struct StringProxy {
    fileprivate let base: StringTTAUtilsCompatiable
    init(proxy: String) {
        base = proxy
    }
}
/// 為 String 結(jié)構(gòu)體添加協(xié)議一致性,并實現(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é)

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

因為這種方法,可以讓你:

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)系作者
  • 序言:七十年代末红且,一起剝皮案震驚了整個濱河市喇勋,隨后出現(xiàn)的幾起案子尸昧,更是在濱河造成了極大的恐慌建芙,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砚作,死亡現(xiàn)場離奇詭異窘奏,居然都是意外死亡,警方通過查閱死者的電腦和手機葫录,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門着裹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人米同,你說我怎么就攤上這事骇扇。” “怎么了面粮?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵少孝,是天一觀的道長。 經(jīng)常有香客問我熬苍,道長稍走,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任柴底,我火速辦了婚禮钱磅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘似枕。我一直安慰自己,他們只是感情好年柠,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布凿歼。 她就那樣靜靜地躺著褪迟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪答憔。 梳的紋絲不亂的頭發(fā)上味赃,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音虐拓,去河邊找鬼心俗。 笑死,一個胖子當(dāng)著我的面吹牛蓉驹,可吹牛的內(nèi)容都是我干的城榛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼态兴,長吁一口氣:“原來是場噩夢啊……” “哼狠持!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瞻润,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤喘垂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绍撞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體正勒,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年傻铣,在試婚紗的時候發(fā)現(xiàn)自己被綠了章贞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡矾柜,死狀恐怖阱驾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情怪蔑,我是刑警寧澤里覆,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站缆瓣,受9級特大地震影響喧枷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弓坞,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一隧甚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渡冻,春花似錦戚扳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽珠增。三九已至,卻和暖如春砍艾,著一層夾襖步出監(jiān)牢的瞬間蒂教,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工脆荷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凝垛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓蜓谋,卻偏偏與公主長得像梦皮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子孤澎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

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