Swift中的命名空間詳解

2022-09-20 21:15:13 字數 2505 閱讀 3546

前言

objective-c 乙個一直以來令人詬病的地方就是沒有命名空間,在應用開發時,所有的**和引用的靜態庫最終都會被編譯到同乙個域和二進位制中。這樣的後果是一旦我們有重複的類名的話,就會導致編譯時的衝突和失敗。為了避免這種事情的發生,objective-c 的型別一般都會加上兩到三個字母的字首,比如 apple 保留的 ns 和 ui 字首,各個系統框架的字首 sk (storekit),cg (coregraphic) 等。objective-c 社群的大部分開發者也遵守了這個約定,一般都會將自己名字縮寫作為字首,把類庫命名為 afnetworking 或者 mbprogresshud 這樣。這種做法可以解決部分問題,至少我們在直接引用不同人的庫時衝突的概率大大降低了,但是字首並不意味著不會衝突,有時候我們確實還是會遇到即使使用字首也仍然相同的情況。另外一種情況是可能你想使用的兩個不同的庫,分別在它們裡面引用了另乙個相同的很流行的第三方庫,而又沒有更改名字。在你分別使用這兩個庫中的乙個時是沒有問題的,但是一旦你將這兩個庫同時加到你的專案中的話,這個大家共用的第三方庫就會和自己發生衝突了。

在 swift 中,由於可以使用命名空間了,即使是名字相同的型別,只要是來自不同的命名空間的話,都是可以和平共處的。和 c# 這樣的顯式在檔案中指定命名空間的做法不同,swift 的命名空間是基於 module 而不是在**中顯式地指明,每個 module 代表了 swift 中的乙個命名空間。也就是說,同乙個 target 裡的型別名稱還是不能相同的。

命名空間namespace在c++、c#裡面是乙個常見概念,swift中也引入了這樣乙個機制,下面來探索一下這個命名空間的來龍去脈。

一、為什麼需要命名空間

簡而言之一句話:為了避免命名的衝突

在開發中,尤其是在多模組開發中,很難保證模組之間的類名不會重複,為了保證不同模組下同名的類可以正常使用而不報錯,引入命名空間來保證即使建立的類名一樣,只要命名空間不一樣,這些類也是不一樣的,所以,這是一種安全機制,用命名空間來防止衝突。可以看出,swift中的類名的完整形式其實是「命名空間+類名」。我們可以嘗試在類中列印當前類來檢視一下完整名字:

override func viewdidload()

//列印結果是:程式設計客棧a.viewcontroller: 0x7fec6a00e5c0>

二、命名空間檢視與修改

從上面的列印結果來看,命名空間是我們專案的名字,那麼如果檢視呢?我們需要用源**的形式開啟info.plist,可以看到裡面有乙個欄位cfbundleexecutable,它對應的值就是命名空間。

如果要修改命名空間,注意不要直接編輯info.plist,可以進入build settings中搜尋product name,然後進行修改。

三、命名空間如何獲取

既然知道可以通過info.plist獲取命名空間,那麼如何在程式中獲取呢?很顯然需要解析info.plist檔案,拿到cfbundleexecutable對應的value值。

let namespace = bundle.main.infodictionary!["cfbundleexecutable"]

// 返回的是乙個可選型

print(namespace!)

四、命名空間在開發中的使用

開發中有一種常見的情形,就是自定義tawww.cppcns.combbarcontroller,然後在裡面新增乙個個子控制器,這裡面常常存在乙個問題:通過乙個控制器名(字串)oxakdxdnfv來建立乙個控制器(類)。下面對比一下objective-c與swift兩種語言的實現方式。

由於objective-c中沒有命名空間,所以寫起來很輕鬆。

//viewdidload中新增乙個個控制器

- (void)viewdidload

//自定的方法中根據傳進來的字串建立控制器

-(void)addn**igationchildvc: (nsstring *) vcname :(nsstring *)title :(nsstring *)nomalimagename :(nsstring *)selectedimagename

swift中命名空間的存在,如果按照上述做法得不到想要的結果,這時候就需要想辦法進行處理

//viewdidload中新增乙個個控制器

override func viewdidload()

建立乙個函式來將控制器的名字轉成具體的類

func stringtovc(vcname:string) -> uiviewcontroller?

//拼接完整的類

guard let vcclass = nsclassfromstring(namespace + "." + vcname) else

//轉換成uiviewcontroller

guard let vctype = vcclass as? uiviewcontroller.type else

//根據型別建立對應的控制器

let vc = vctype.init()

return vc}總結

本文標題: swift中的命名空間詳解

本文位址: http:/ruanjian/swift/247478.html

swift 命名空間

原文 myframework.swift 這個檔案存在於 myframework.framework 中 public class myclass class myclass 在使用時,如果出現可能衝突的時候,我們需要在型別名稱前面加上 module 的名字 也就是 target 的名字 mycla...

Swift 命名空間

myframework.swift 這個檔案存在於myframework.framework中 public class myclass class myclass 在使用時,在可能出現衝突的時候,我們需要在型別名稱前面加上module的名字 也就是target的名字 myclass hello m...

Swift建立命名空間

第一種實現方式 原理 1.泛型類 2.泛型協議 3.協議拓展 定義泛型類 public final class ykkit 定義泛型協議 public protocol ykkitcompatible 協議的擴充套件 public extension ykkitcompatible 實現命名空間yk...