Swift命名空間

之前在使用RxSwfit的時(shí)候?qū)?rx這個(gè)東西的一直有些疑問筋现,不清楚實(shí)現(xiàn)原理唐础,趁著現(xiàn)在有些空余時(shí)間箱歧,打算深入研究下,于是有了這篇文章一膨。

通過學(xué)習(xí)呀邢,了解到rx其實(shí)就是一個(gè)命名空間的實(shí)現(xiàn),關(guān)于Swift命名空間的說明豹绪,參考喵神的這篇文章价淌。

關(guān)于命名沖突

Swift的命名空間是以模塊來劃分的,一個(gè)模塊表示一個(gè)命名空間瞒津,我們進(jìn)行APP開發(fā)是蝉衣,默認(rèn)添加到主target的內(nèi)容是同處于同一個(gè)命名空間的。如果用Cocoapod的方式導(dǎo)入的第三方庫巷蚪,是以一個(gè)單獨(dú)的target存在病毡,不會(huì)存在命名沖突。如果是以源碼的方式導(dǎo)入工程中屁柏,很有可能發(fā)生命名沖突啦膜。所以,為了安全起見淌喻,第三方庫都會(huì)使用命名空間這種方式來防止沖突僧家。在Objective-C上沒有命名空間,一般是使用方法名前面加前綴的方式避免沖突裸删。

命名空間原理


let text = usernameLabel.rx.text.orEmpty.asObservable()

如果你對RxSwift熟悉的話八拱,應(yīng)該看過不少類似的代碼。觀察上面的代碼涯塔,發(fā)現(xiàn)可以通過點(diǎn)語法訪問rx乘粒,這說明rx是一個(gè)屬性,rx又可以用點(diǎn)語法訪問UILabel的text屬性伤塌,說明rx是個(gè)數(shù)據(jù)結(jié)構(gòu)灯萍。

小結(jié):
1、rx是個(gè)數(shù)據(jù)結(jié)構(gòu)
2每聪、rx是個(gè)屬性

實(shí)現(xiàn)命名空間

有了上面的說明旦棉,我們可以定義一個(gè)名為ButtonNameSpace的命名空間結(jié)構(gòu)體


struct ButtonNameSpace {

 func hello() {

 print("Hello")

 }

}

然后,我們?yōu)閁IButton這個(gè)類添加一個(gè)nameSpace計(jì)算屬性药薯,nameSpace返回一個(gè)ButtonNameSpace結(jié)構(gòu)體的實(shí)例


extension UIButton {

 var nameSpace: ButtonNameSpace {

 return ButtonNameSpace()

 }

}

現(xiàn)在我們可以用如下方式使用


UIButton().nameSpace.hello() // 輸出hello

這樣的命名空間其實(shí)沒有作用绑洛,因?yàn)闊o法訪問UIButton的屬性和函數(shù)。

下面為ButtonNameSpace加上一些有用的東西


struct ButtonNameSpace {

 private let button: UIButton

 init(button: UIButton) {

 self.button = button

 }

 func hello() {

 print("Hello \(button.titleLabel?.text ?? "")")

 }

}

修改UIButton的擴(kuò)展的實(shí)現(xiàn)


extension ButtonNameSpace {

 var nameSapce: ButtonNameSapce {

 return ButtonNameSapce(button: self)

 }

}

現(xiàn)在命名空間更有意義了童本,因?yàn)樗鼘?chuàng)建它的對象真屯,有了一個(gè)引用。實(shí)際上穷娱,命名空間的真正目的是對創(chuàng)建它的對象保存一個(gè)引用绑蔫。

如果現(xiàn)在我想為UILabel也添加一個(gè)命名空間运沦,那么我還要為UILabel添加一個(gè)LabelNameSpace的命名空間,這樣顯然是不太聰明的做法配深,命名空間結(jié)構(gòu)體應(yīng)該是通用的携添,讓我們定義一個(gè)通用的命名空間結(jié)構(gòu)體。

實(shí)現(xiàn)泛型的命名空間

定義泛型的命名空間結(jié)構(gòu)體


struct MyNameSpace<Base> {

 private let base: Base

 init(base: Base) {

 self.base = base

 }

}

現(xiàn)在我們可以為UIButton和UILabel添加hello方法了


extension UIButton {

 var nameSpace: MyNameSpace<UIButton> {

 return MyNameSpace(base: self)

 }

}

extension MyNameSpace where Base: UIButton {

 func hello() {

 print("Hi \(base.titleLabel?.text ?? "")")

 }

}

let bnt = UIButton()

bnt("My button", for: .normal)

bnt.nameSpace.hello(). // 輸出:Hi My button

extension UILabel {

 var nameSpace: MyNameSpace<UILabel> {

 return MyNameSpace(base: self)

 }

}

extension MyNameSpace where Base: UILabel {

 func hello() {

 print("Hi \(base?.text ?? "")")

 }

}

觀察上面的代碼篓叶,為UIButton和UILabel添加擴(kuò)展的代碼基本是一樣的烈掠,都有nameSpace計(jì)算屬性,返回的都是命名空間結(jié)構(gòu)體的實(shí)例缸托,顯然我們可以用更優(yōu)雅的代碼實(shí)現(xiàn)上面的功能左敌,沒錯(cuò),就是協(xié)議擴(kuò)展俐镐。

協(xié)議擴(kuò)展

protocol NameSpaceWrappable {
    associatedtype T
    var rx: T { get }
    static var rx: T.Type { get }
}

extension NameSpaceWrappable {
    var rx: MyNameSpace<Self> {
        return MyNameSpace<Self>(base: self)
    }

    static var rx: MyNameSpace<Self>.Type {
        return MyNameSpace<Self>.self
    }
}

觀察上面的代碼母谎,我們定義了一個(gè)NameSpaceWrappable的協(xié)議,包含一個(gè)泛型實(shí)例屬性和一個(gè)類屬性京革,分別返回MyNameSpace泛型結(jié)構(gòu)體的實(shí)例和類。

現(xiàn)在我們?yōu)閁IButton實(shí)現(xiàn)上述功能幸斥,只需讓UIButton遵循NameSpaceWrappable協(xié)議匹摇,就能得到一個(gè)名為rx的MyNameSpace結(jié)構(gòu)體的實(shí)例屬性和名為rx的類屬性。

extension UIButton: NameSpaceWrappable {}
let btn = UIButton()
btn.titleLabel?.text = "ni hao"
btn.rx.hello()

查看Reactive.swift的源碼甲葬,發(fā)現(xiàn)正是這樣實(shí)現(xiàn)的廊勃。

總結(jié)

同一個(gè)模塊中實(shí)現(xiàn)命名空間,其實(shí)就是通過類型嵌套限定使用范圍经窖。

水平有限坡垫,如有錯(cuò)誤的地方,請務(wù)必留言告訴我画侣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冰悠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子配乱,更是在濱河造成了極大的恐慌溉卓,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搬泥,死亡現(xiàn)場離奇詭異桑寨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)忿檩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門煌集,熙熙樓的掌柜王于貴愁眉苦臉地迎上來圆存,“玉大人,你說我怎么就攤上這事舞终。” “怎么了漱抓?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我徒役,道長,這世上最難降的妖魔是什么窖壕? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任忧勿,我火速辦了婚禮,結(jié)果婚禮上瞻讽,老公的妹妹穿的比我還像新娘鸳吸。我一直安慰自己,他們只是感情好速勇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布晌砾。 她就那樣靜靜地躺著,像睡著了一般烦磁。 火紅的嫁衣襯著肌膚如雪养匈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天都伪,我揣著相機(jī)與錄音呕乎,去河邊找鬼。 笑死陨晶,一個(gè)胖子當(dāng)著我的面吹牛猬仁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播先誉,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼湿刽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了褐耳?” 一聲冷哼從身側(cè)響起诈闺,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铃芦,沒想到半個(gè)月后买雾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杨帽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年漓穿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片注盈。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晃危,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情僚饭,我是刑警寧澤震叮,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站鳍鸵,受9級特大地震影響苇瓣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偿乖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一击罪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贪薪,春花似錦媳禁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至霍弹,卻和暖如春毫别,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背典格。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工岛宦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钝计。 一個(gè)月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像齐佳,于是被迫代替她去往敵國和親私恬。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

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