Swift中的命名空間詳解
前言
Objective-C 一個(gè)一直以來(lái)令人詬病的地方就是沒(méi)有命名空間,在應(yīng)用開(kāi)發(fā)時(shí),所有的代碼和引用的靜態(tài)庫(kù)最終都會(huì)被編譯到同一個(gè)域和二進(jìn)制中。這樣的后果是一旦我們有重復(fù)的類名的話,就會(huì)導(dǎo)致編譯時(shí)的沖突和失敗。為了避免這種事情的發(fā)生,Objective-C 的類型一般都會(huì)加上兩到三個(gè)字母的前綴,比如 Apple 保留的 NS 和 UI 前綴,各個(gè)系統(tǒng)框架的前綴 SK (StoreKit),CG (CoreGraphic) 等。Objective-C 社區(qū)的大部分開(kāi)發(fā)者也遵守了這個(gè)約定,一般都會(huì)將自己名字縮寫(xiě)作為前綴,把類庫(kù)命名為 AFNetworking 或者 MBProgressHUD 這樣。這種做法可以解決部分問(wèn)題,至少我們?cè)谥苯右貌煌说膸?kù)時(shí)沖突的概率大大降低了,但是前綴并不意味著不會(huì)沖突,有時(shí)候我們確實(shí)還是會(huì)遇到即使使用前綴也仍然相同的情況。另外一種情況是可能你想使用的兩個(gè)不同的庫(kù),分別在它們里面引用了另一個(gè)相同的很流行的第三方庫(kù),而又沒(méi)有更改名字。在你分別使用這兩個(gè)庫(kù)中的一個(gè)時(shí)是沒(méi)有問(wèn)題的,但是一旦你將這兩個(gè)庫(kù)同時(shí)加到你的項(xiàng)目中的話,這個(gè)大家共用的第三方庫(kù)就會(huì)和自己發(fā)生沖突了。
在 Swift 中,由于可以使用命名空間了,即使是名字相同的類型,只要是來(lái)自不同的命名空間的話,都是可以和平共處的。和 C# 這樣的顯式在文件中指定命名空間的做法不同,Swift 的命名空間是基于 module 而不是在代碼中顯式地指明,每個(gè) module 代表了 Swift 中的一個(gè)命名空間。也就是說(shuō),同一個(gè) target 里的類型名稱還是不能相同的。
命名空間namespace在C++、C#里面是一個(gè)常見(jiàn)概念,Swift中也引入了這樣一個(gè)機(jī)制,下面來(lái)探索一下這個(gè)命名空間的來(lái)龍去脈。
一、為什么需要命名空間
簡(jiǎn)而言之一句話:為了避免命名的沖突
在開(kāi)發(fā)中,尤其是在多模塊開(kāi)發(fā)中,很難保證模塊之間的類名不會(huì)重復(fù),為了保證不同模塊下同名的類可以正常使用而不報(bào)錯(cuò),引入命名空間來(lái)保證即使創(chuàng)建的類名一樣,只要命名空間不一樣,這些類也是不一樣的,所以,這是一種安全機(jī)制,用命名空間來(lái)防止沖突??梢钥闯觯琒wift中的類名的完整形式其實(shí)是“命名空間+類名”。我們可以嘗試在類中打印當(dāng)前類來(lái)查看一下完整名字:
override func viewDidLoad() { super.viewDidLoad() print(self) } //打印結(jié)果是:<AA.ViewController: 0x7fec6a00e5c0>
二、命名空間查看與修改
從上面的打印結(jié)果來(lái)看,命名空間是我們項(xiàng)目的名字,那么如果查看呢?我們需要用源代碼的形式打開(kāi)Info.plist,可以看到里面有一個(gè)字段CFBundleExecutable,它對(duì)應(yīng)的值就是命名空間。
如果要修改命名空間,注意不要直接編輯Info.plist,可以進(jìn)入Build Settings中搜索Product Name,然后進(jìn)行修改。
三、命名空間如何獲取
既然知道可以通過(guò)Info.plist獲取命名空間,那么如何在程序中獲取呢?很顯然需要解析Info.plist文件,拿到CFBundleExecutable對(duì)應(yīng)的value值。
let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] // 返回的是一個(gè)可選型 print(namespace!)
四、命名空間在開(kāi)發(fā)中的使用
開(kāi)發(fā)中有一種常見(jiàn)的情形,就是自定義TabBarController,然后在里面添加一個(gè)個(gè)子控制器,這里面常常存在一個(gè)問(wèn)題:通過(guò)一個(gè)控制器名(字符串)來(lái)創(chuàng)建一個(gè)控制器(類)。下面對(duì)比一下Objective-C與Swift兩種語(yǔ)言的實(shí)現(xiàn)方式。
由于Objective-C中沒(méi)有命名空間,所以寫(xiě)起來(lái)很輕松。
//viewDidLoad中添加一個(gè)個(gè)控制器 - (void)viewDidLoad { [super viewDidLoad]; [self addNavigationChildVC:@"ContactViewController" :@"聯(lián)系人" :@"tabbar_contacts" :@"tabbar_contactsHL"]; } //自定的方法中根據(jù)傳進(jìn)來(lái)的字符串創(chuàng)建控制器 -(void)addNavigationChildVC: (NSString *) vcName :(NSString *)title :(NSString *)nomalImageName :(NSString *)selectedImageName { //創(chuàng)建控制器 Class class = NSClassFromString(vcName); UIViewController *vc = [[class alloc]init]; ... }
Swift中命名空間的存在,如果按照上述做法得不到想要的結(jié)果,這時(shí)候就需要想辦法進(jìn)行處理
//viewDidLoad中添加一個(gè)個(gè)控制器 override func viewDidLoad() { super.viewDidLoad() addChildViewController(vcName: "ContactsViewController", title: "聯(lián)系人", image: "tabbar_contacts", selectedImage: "tabbar_contactsHL") } //創(chuàng)建一個(gè)函數(shù)來(lái)將控制器的名字轉(zhuǎn)成具體的類 func stringToVC(vcName:String) -> UIViewController? { //獲取命名空間 guard let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String else { print("獲取失敗") return nil } //拼接完整的類 guard let vcClass = NSClassFromString(namespace + "." + vcName) else { print("拼接失敗") return nil } //轉(zhuǎn)換成UIViewController guard let vcType = vcClass as? UIViewController.Type else { print("轉(zhuǎn)換失敗") return nil } //根據(jù)類型創(chuàng)建對(duì)應(yīng)的控制器 let vc = vcType.init() return vc }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)我們的支持。
上一篇:通過(guò)Notification.Name看Swift是如何優(yōu)雅的解決String硬編碼
欄 目:Swift
下一篇:swift4 使用DrawerController實(shí)現(xiàn)側(cè)滑菜單功能的示例代碼
本文標(biāo)題:Swift中的命名空間詳解
本文地址:http://mengdiqiu.com.cn/a1/Swift/11939.html
您可能感興趣的文章
- 01-11swift中defer幾個(gè)簡(jiǎn)單的使用場(chǎng)景詳解
- 01-11Swift利用Decodable解析JSON的一個(gè)小問(wèn)題詳解
- 01-11Swift中defer關(guān)鍵字推遲執(zhí)行示例詳解
- 01-11Swift中初始化init的方法小結(jié)
- 01-11Swift中定義單例的方法實(shí)例
- 01-11Swift利用純代碼實(shí)現(xiàn)時(shí)鐘效果實(shí)例代碼
- 01-11Swift中排序算法的簡(jiǎn)單取舍詳解
- 01-11Swift如何為設(shè)置中心添加常用功能
- 01-11Swift Json實(shí)例詳細(xì)解析
- 01-11Swift利用指紋識(shí)別或面部識(shí)別為應(yīng)用添加私密保護(hù)功能


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-11Swift利用Decodable解析JSON的一個(gè)小問(wèn)題
- 01-11swift中defer幾個(gè)簡(jiǎn)單的使用場(chǎng)景詳解
- 01-11Swift中初始化init的方法小結(jié)
- 01-11Swift中defer關(guān)鍵字推遲執(zhí)行示例詳解
- 01-11Swift利用純代碼實(shí)現(xiàn)時(shí)鐘效果實(shí)例代碼
- 01-11Swift中定義單例的方法實(shí)例
- 01-11Swift中排序算法的簡(jiǎn)單取舍詳解
- 01-11Swift Json實(shí)例詳細(xì)解析
- 01-11Swift如何為設(shè)置中心添加常用功能
- 01-11Swift利用指紋識(shí)別或面部識(shí)別為應(yīng)用添
隨機(jī)閱讀
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文