前言
Objective-C 一個一直以來令人詬病的地方就是沒有命名空間,在應用開發(fā)時,所有的代碼和引用的靜態(tài)庫最終都會被編譯到同一個域和二進制中。這樣的后果是一旦我們有重復的類名的話,就會導致編譯時的沖突和失敗。為了避免這種事情的發(fā)生,Objective-C 的類型一般都會加上兩到三個字母的前綴,比如 Apple 保留的 NS 和 UI 前綴,各個系統(tǒng)框架的前綴 SK (StoreKit),CG (CoreGraphic) 等。Objective-C 社區(qū)的大部分開發(fā)者也遵守了這個約定,一般都會將自己名字縮寫作為前綴,把類庫命名為 AFNetworking 或者 MBProgressHUD 這樣。這種做法可以解決部分問題,至少我們在直接引用不同人的庫時沖突的概率大大降低了,但是前綴并不意味著不會沖突,有時候我們確實還是會遇到即使使用前綴也仍然相同的情況。另外一種情況是可能你想使用的兩個不同的庫,分別在它們里面引用了另一個相同的很流行的第三方庫,而又沒有更改名字。在你分別使用這兩個庫中的一個時是沒有問題的,但是一旦你將這兩個庫同時加到你的項目中的話,這個大家共用的第三方庫就會和自己發(fā)生沖突了。
在 Swift 中,由于可以使用命名空間了,即使是名字相同的類型,只要是來自不同的命名空間的話,都是可以和平共處的。和 C# 這樣的顯式在文件中指定命名空間的做法不同,Swift 的命名空間是基于 module 而不是在代碼中顯式地指明,每個 module 代表了 Swift 中的一個命名空間。也就是說,同一個 target 里的類型名稱還是不能相同的。
<a >原文鏈接</a>(侵權刪)
1.初識
我們來看看如下代碼的打印,這是我講兩個控制器作為MainViewController的childvc的代碼,只做講解
import UIKit
class MainViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
setupChildViewController(TestFirstViewController())
setupChildViewController(TestSecondViewController())
}
private func setupChildViewController(vc:UIViewController) {
print(vc)
addChildViewController(vc)
}
}
我們來看看打印結果,如下圖

我們看到,打印的控制器前面有nameSpaceTest的打印顯示,這里nameSpaceTest就是我們所說的命名空間的名稱,一般來說命名空間是我們的項目名稱
1.1修改命名空間
我們再來看看如何修改我們項目的命名空間,如下圖

在項目中,build settings下搜索product name之后雙擊修改即可,如圖我吧命名空間改成iOSCoderZZJ,在運行上面的那段代碼,看看控制臺的打印情況,如下圖

從圖片的打印看來,命名空間已經(jīng)被咱們修改了
1.2動態(tài)加載命名空間
在開發(fā)中,咱們可以輕而易舉的得知自己項目的命名空間,但是寫在代碼中,如果用字符串"nameSpaceTest"或者"iOSCoderZZJ"寫死,肯定會覺得非常low吧,那么咱們就來看看如何動態(tài)的獲取項目的命名空間,眾所周知,項目的所有配置信息都在info.plist中,那么我們就去找找看吧,如下圖

點擊后,如下圖的key對應的就是項目的命名空間信息

既然我們都知道了套路,看看代碼如何寫吧
//動態(tài)獲取命名空間(常規(guī)寫法出現(xiàn)的錯誤寫法)
let ns = NSBundle.mainBundle().infoDictionary["CFBundleExecutable"]
這樣我們就拿到了項目的命名空間,但是!!!!!!!如果你復制上面這句代碼,一定會報錯的,這里要插播一個知識,在Swift開發(fā)中,我們經(jīng)常會看到?或者!這樣的字符,?代表可選類型,即該對象可以沒有值,!表示該對象必須有值,在Swift中我們要經(jīng)常按住option鍵去看看一個方法的參數(shù)或者返回值是否要必須有值,如下圖

那么我們把正確的代碼貼出來,分析一下吧
let ns = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String
首先,我們看第一個驚嘆號,我們從infoDictionary中用key取值,我們要告訴編譯器,該字典一定有值,我們才能去取,之后我們把取到的value值強轉成了String類型,我們?yōu)槭裁从忠赼s后面加上一個驚嘆號呢,那是因為雖然字典里有值,但是我強轉的時候編譯器并不確定CFBundleExecutable這個key的對應的value是否為空,因為用key去取字典中的value使用的是字符串類型,又因為它是字符串,所以這個key是可能寫錯或者瞎寫的,錯誤的key更不可能取出正確的value值,所以我們在強制轉換的時候在as后面加上了驚嘆號,表示這個key取出的value是一定有值的,這樣我們就拿到了項目的命名空間
PS:在Swift中強制轉化用的是as關鍵字,并且因為Swift是一門強語言,所以很多錯誤在還未編譯時就提示給你,減少了運行時報錯的幾率
1.3用途
由于命名空間可以修改,所以項目中單純的用項目名稱代替命名空間的做法并不可靠. 為了滿足項目中某些需求,比如:活動期間需要顯示與平時完全不同風格的界面,活動結束后又要修改回來,我們不可能在短期連發(fā)兩個版本,這個就需要跟后臺就行互動,將類名提前預留在后臺,程序里面使用動態(tài)加載類來實現(xiàn)
<a >原文鏈接</a>(侵權刪)
//1.動態(tài)獲取命名空間
let ns = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String
//2.將字符串轉為類,其中firstTestControllerName完全可以是后臺返回給我們的該類的名稱,然后去動態(tài)創(chuàng)建
let cls : AnyClass? = NSClassFromString(ns + "." + firstTestControllerName)
//將AnyClass轉換為指定類型
let vcCls = cls as! UIViewController.Type
//3.通過類創(chuàng)建一個對象
let vc = vcCls.init()
1.4 Swift中導入第三方框架
上面介紹了,OC中沒有命名空間的概念,所以我們導入第三方框架的時候,可以將該框架直接拖入工程,進行使用,但是Swift中有了命名空間的概念,所以直接拖入工程會有些問題,我們需要創(chuàng)建一個橋接的主頭文件,因為Swift和OC可以混編,所以很多的OC實現(xiàn)的框架也是可以使用的,例如眾所周知的AFNetWorking,如下圖

但是這樣我們還是不能使用的,還要進行如下操作

1.4.1 Swift中使用cocoapods
雖然手動導入后可以使用第三方框架的東西了.但是你們有沒有覺得還是很麻煩,又要創(chuàng)建.h文件,又要去build setting中搞一搞,所以Swift中最好還是使用cocoapods導入第三方的框架,這樣你導入的文件就會在同一個命名空間下,省去很多苦惱,但是注意一點,在Swift中使用cocoapods,需要在Podfile最前面加上一句話,use_frameworks!如下圖

導入成功后,在需要的地方導入即可

那么現(xiàn)在就是見證奇跡的時刻,既然導入了咱們就使用下吧,比如初始化一個對象
AFHTTPSessionManager.init(),我們按住cmdmand鍵點AFHTTPSessionManager擊跳進去看看里面,如下圖

所有的OC代碼全部編譯成了Swift的代碼,所以說cocoapods導入第三方框架是非常適合Swift開發(fā)的
總結
今天給大家介紹了Swift的命名空間以及第三方框架的導入,如果有錯誤的地方請大家多多指正
我是iOS開發(fā)的小菜雞,希望有天可以變成雄鷹
旅途很長,還需修行