Swift中的命名空间详解

2020-01-09 00:13:49王冬梅

既然知道可以通过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
}