Swift中的命名空间详解

 更新时间:2018年12月16日 14:43:43   作者:YungFan  
这篇文章主要给大家介绍了关于Swift中命名空间的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

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() {
super.viewDidLoad()
print(self)
}
//打印结果是:<AA.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!)

四、命名空间在开发中的使用

开发中有一种常见的情形,就是自定义TabBarController,然后在里面添加一个个子控制器,这里面常常存在一个问题:通过一个控制器名(字符串)来创建一个控制器(类)。下面对比一下Objective-C与Swift两种语言的实现方式。

由于Objective-C中没有命名空间,所以写起来很轻松。

//viewDidLoad中添加一个个控制器
- (void)viewDidLoad {
 [super viewDidLoad];
 [self addNavigationChildVC:@"ContactViewController" :@"联系人" :@"tabbar_contacts" :@"tabbar_contactsHL"];
}

//自定的方法中根据传进来的字符串创建控制器
-(void)addNavigationChildVC: (NSString *) vcName :(NSString *)title :(NSString *)nomalImageName :(NSString *)selectedImageName {
 //创建控制器
 Class class = NSClassFromString(vcName);
 UIViewController *vc = [[class alloc]init];
 ...
}

Swift中命名空间的存在,如果按照上述做法得不到想要的结果,这时候就需要想办法进行处理

//viewDidLoad中添加一个个控制器
override func viewDidLoad() {
 super.viewDidLoad()
 addChildViewController(vcName: "ContactsViewController", title: "联系人", image: "tabbar_contacts", selectedImage: "tabbar_contactsHL")
}

//创建一个函数来将控制器的名字转成具体的类
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
 } 
 //转换成UIViewController
 guard let vcType = vcClass as? UIViewController.Type else {
  print("转换失败")
  return nil
 } 
 //根据类型创建对应的控制器
 let vc = vcType.init()
 return vc
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • 使用Swift实现iOS App中解析XML格式数据的教程

    使用Swift实现iOS App中解析XML格式数据的教程

    这篇文章主要介绍了使用Swift实现iOS App中解析XML格式数据的教程,讲到了iOS中提供的NSXMLParser和NSXMLParserDelegate两个API的用法,需要的朋友可以参考下
    2016-04-04
  • RxSwift学习教程之类型对象Subject详解

    RxSwift学习教程之类型对象Subject详解

    这篇文章主要给大家介绍了关于RxSwift学习教程之类型对象Subject的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧。
    2017-09-09
  • Swift利用CoreData实现一个通讯录存储详解

    Swift利用CoreData实现一个通讯录存储详解

    这篇文章主要给大家介绍了关于Swift利用CoreData实现一个通讯录存储的相关资料,本文是大家学习coreDate的基础问题,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-12-12
  • swift where与匹配模式的实例详解

    swift where与匹配模式的实例详解

    这篇文章主要介绍了swift where与匹配模式的实例详解的相关资料,这里附有简单的示例代码,讲的比较清楚,需要的朋友可以参考下
    2017-07-07
  • swift实现简易计算器项目

    swift实现简易计算器项目

    这篇文章主要为大家详细介绍了swift实现简易计算器项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • Swift调用Objective-C代码

    Swift调用Objective-C代码

    目前Swift语言所编写的应用才刚刚可以使用Xcode 6 GM版本提交,而Objective-C作为苹果的主开发语言存在了很多年了。目前尚无成熟的Swift库可用,所以当前编写应用可以说基本离不开调用Objective-C代码的情况。
    2014-09-09
  • mac git xcrun error active developer path 错误

    mac git xcrun error active developer path 错误

    本文主要是讲诉了如何解决在mac下使用git;xcode4.6的环境时,出现了错误(mac git xcrun error active developer path)的解决办法,希望对大家有所帮助
    2014-09-09
  • SwiftUI 登录界面布局实现示例详解

    SwiftUI 登录界面布局实现示例详解

    这篇文章主要为大家介绍了SwiftUI 登录界面布局实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • SwiftUI中TabView组件的常规使用

    SwiftUI中TabView组件的常规使用

    这篇文章主要给大家介绍了关于SwiftUI中TabView组件的常规使用,文中通过实例代码介绍的非常详细,对大家学习或者使用SwiftUI具有一定的参考学习价值,需要的朋友可以参考下
    2022-06-06
  • Swift中的指针操作详解

    Swift中的指针操作详解

    从传统的C代码和与之无缝配合的Objective-C代码迁移到Swift并非小工程,我们的代码库肯定会时不时出现一些和C协作的地方,如果想要继续使用那些C API的话,了解一些基本的Swift指针操作和使用的知识会很有帮助。下面通过这篇文章一起来学习下吧。
    2017-01-01

最新评论