-
1.何为命名空间
OC中没有命名空间的概念,在进行应用开发时,所有的代码和引用的静态库最终会被编译到同一个域和二进制文件中。这样当两个类名重复的时候,就会导致编译冲突和失败。这也就是为什么我们在写OC代码的时候要添加类名前缀的原因。比如苹果本身保留的前缀UI和NS 还有各个系统框架的前缀AF、SD等,这样做可以大大降低引起冲突的几率,但是风险仍然存在,如果你在项目中同时加载进两个不同的库,而这两个库都分别引用了同一个第三方库而没有修改名字,这样就会发生冲突。
Swift由于命名空间的存在,既是两个名称相同的类,只要他们来自不同的命名空间就不会产生编译时的冲突。
"在 Swift 中,由于可以使用命名空间了,即使是名字相同的类型,只要是来自不同的命名空间的话,都是可以和平共处的。和 C# 这样的显式在文件中指定命名空间的做法不同,Swift 的命名空间是基于 module 而不是在代码中显式地指明,每个 module 代表了 Swift 中的一个命名空间。也就是说,同一个 target 里的类型名称还是不能相同的。在我们进行 app 开发时,默认添加到 app 的主 target 的内容都是处于同一个命名空间中的,我们可以通过创建 Cocoa (Touch) Framework 的 target 的方法来新建一个 module,这样我们就可以在两个不同的 target 中添加同样名字的类型了。
在swift中类名的组成格式是 namespace.类名。比如我们在任意一个控制器的viewDidLoad()方法中打印self,打印结果是:
这里Webo就是命名空间,默认是项目的名字。
-
2.如果查看命名空间
swift中命名空间默认为项目的名称,具体查看的办法为在info.plist文件中,键名为"CFBundleExecutable"的字符串:
-
3如何更改命名空间
-
4命名空间对动态加载类的影响(本人现在只接触过这一个😜)
在oc中我们想要动态的创建一个类的做法是,直接通过字符串穿件类,如下:
NSString *classNameStr = @"className";
id object = [[NSClassFromString(classNameStr) alloc]init];
但是在swift中由于命名空间的存在,如果还用上面的方法通过字符串动态的创建类是不可以的(得到的会是空)。swift通过字符串动态的创建类我们需要在字符串的前面加上 ”命名空间.“(没有双引号,但是有点),具体如下:
let classNameStr = "classNameStr"
//动态获得命名空间
let name = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String
//这里以控制器为例
let vc:AnyClass? = NSClassFromString(name + "." + classNameStr)
if let vc = vc {
let nameVc = vc as! UIViewController.Type
//nameVc就是通过字符串动态加载后的类,我们可以通过他创建新的实例
let newObject = nameVc.init()
}