Swift命名空间,以及Swift导入第三方框架

前言

Objective-C 一个一直以来令人诟病的地方就是没有命名空间,在应用开发时,所有的代码和引用的静态库最终都会被编译到同一个域和二进制中。这样的后果是一旦我们有重复的类名的话,就会导致编译时的冲突和失败。为了避免这种事情的发生,Objective-C 的类型一般都会加上两到三个字母的前缀,比如 Apple 保留的 NS 和 UI 前缀,各个系统框架的前缀 SK (StoreKit),CG (CoreGraphic) 等。Objective-C 社区的大部分开发者也遵守了这个约定,一般都会将自己名字缩写作为前缀,把类库命名为 AFNetworking 或者 MBProgressHUD 这样。这种做法可以解决部分问题,至少我们在直接引用不同人的库时冲突的概率大大降低了,但是前缀并不意味着不会冲突,有时候我们确实还是会遇到即使使用前缀也仍然相同的情况。另外一种情况是可能你想使用的两个不同的库,分别在它们里面引用了另一个相同的很流行的第三方库,而又没有更改名字。在你分别使用这两个库中的一个时是没有问题的,但是一旦你将这两个库同时加到你的项目中的话,这个大家共用的第三方库就会和自己发生冲突了。

在 Swift 中,由于可以使用命名空间了,即使是名字相同的类型,只要是来自不同的命名空间的话,都是可以和平共处的。和 C# 这样的显式在文件中指定命名空间的做法不同,Swift 的命名空间是基于 module 而不是在代码中显式地指明,每个 module 代表了 Swift 中的一个命名空间。也就是说,同一个 target 里的类型名称还是不能相同的。
原文链接(侵权删)

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)
    }
}

我们来看看打印结果,如下图

WeChat_1469866368.jpeg

我们看到,打印的控制器前面有nameSpaceTest的打印显示,这里nameSpaceTest就是我们所说的命名空间的名称,一般来说命名空间是我们的项目名称

1.1修改命名空间

我们再来看看如何修改我们项目的命名空间,如下图

Swift命名空间,以及Swift导入第三方框架_第1张图片
WeChat_1469869899.jpeg

在项目中,build settings下搜索product name之后双击修改即可,如图我吧命名空间改成iOSCoderZZJ,在运行上面的那段代码,看看控制台的打印情况,如下图

WeChat_1469870116.jpeg

从图片的打印看来,命名空间已经被咱们修改了

1.2动态加载命名空间

在开发中,咱们可以轻而易举的得知自己项目的命名空间,但是写在代码中,如果用字符串"nameSpaceTest"或者"iOSCoderZZJ"写死,肯定会觉得非常low吧,那么咱们就来看看如何动态的获取项目的命名空间,众所周知,项目的所有配置信息都在info.plist中,那么我们就去找找看吧,如下图

Swift命名空间,以及Swift导入第三方框架_第2张图片
WeChat_1469870535.jpeg

点击后,如下图的key对应的就是项目的命名空间信息

Swift命名空间,以及Swift导入第三方框架_第3张图片
WeChat_1469870597.jpeg

既然我们都知道了套路,看看代码如何写吧

//动态获取命名空间(常规写法出现的错误写法)
 let ns = NSBundle.mainBundle().infoDictionary["CFBundleExecutable"]

这样我们就拿到了项目的命名空间,但是!!!!!!!如果你复制上面这句代码,一定会报错的,这里要插播一个知识,在Swift开发中,我们经常会看到?或者!这样的字符,?代表可选类型,即该对象可以没有值,!表示该对象必须有值,在Swift中我们要经常按住option键去看看一个方法的参数或者返回值是否要必须有值,如下图

Swift命名空间,以及Swift导入第三方框架_第4张图片
WeChat_1469871012.jpeg

那么我们把正确的代码贴出来,分析一下吧

let ns = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String

首先,我们看第一个惊叹号,我们从infoDictionary中用key取值,我们要告诉编译器,该字典一定有值,我们才能去取,之后我们把取到的value值强转成了String类型,我们为什么又要在as后面加上一个惊叹号呢,那是因为虽然字典里有值,但是我强转的时候编译器并不确定CFBundleExecutable这个key的对应的value是否为空,因为用key去取字典中的value使用的是字符串类型,又因为它是字符串,所以这个key是可能写错或者瞎写的,错误的key更不可能取出正确的value值,所以我们在强制转换的时候在as后面加上了惊叹号,表示这个key取出的value是一定有值的,这样我们就拿到了项目的命名空间
PS:在Swift中强制转化用的是as关键字,并且因为Swift是一门强语言,所以很多错误在还未编译时就提示给你,减少了运行时报错的几率

1.3用途

由于命名空间可以修改,所以项目中单纯的用项目名称代替命名空间的做法并不可靠. 为了满足项目中某些需求,比如:活动期间需要显示与平时完全不同风格的界面,活动结束后又要修改回来,我们不可能在短期连发两个版本,这个就需要跟后台就行互动,将类名提前预留在后台,程序里面使用动态加载类来实现
原文链接(侵权删)

        //1.动态获取命名空间
        let ns = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String
        //2.将字符串转为类,其中firstTestControllerName完全可以是后台返回给我们的该类的名称,然后去动态创建
        let cls : AnyClass? = NSClassFromString(ns + "." + firstTestControllerName)
        //将AnyClass转换为指定类型
        let vcCls = cls as! UIViewController.Type
        //3.通过类创建一个对象
        let vc = vcCls.init()
1.4 Swift中导入第三方框架

上面介绍了,OC中没有命名空间的概念,所以我们导入第三方框架的时候,可以将该框架直接拖入工程,进行使用,但是Swift中有了命名空间的概念,所以直接拖入工程会有些问题,我们需要创建一个桥接的主头文件,因为Swift和OC可以混编,所以很多的OC实现的框架也是可以使用的,例如众所周知的AFNetWorking,如下图

Swift命名空间,以及Swift导入第三方框架_第5张图片
WeChat_1469876625.jpeg

但是这样我们还是不能使用的,还要进行如下操作

Swift命名空间,以及Swift导入第三方框架_第6张图片
WeChat_1469877062.jpeg
1.4.1 Swift中使用cocoapods

虽然手动导入后可以使用第三方框架的东西了.但是你们有没有觉得还是很麻烦,又要创建.h文件,又要去build setting中搞一搞,所以Swift中最好还是使用cocoapods导入第三方的框架,这样你导入的文件就会在同一个命名空间下,省去很多苦恼,但是注意一点,在Swift中使用cocoapods,需要在Podfile最前面加上一句话,use_frameworks!如下图

WeChat_1469877620.jpeg

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

WeChat_1469877934.jpeg

那么现在就是见证奇迹的时刻,既然导入了咱们就使用下吧,比如初始化一个对象 AFHTTPSessionManager.init(),我们按住 cmdmand键点 AFHTTPSessionManager击跳进去看看里面,如下图

Swift命名空间,以及Swift导入第三方框架_第7张图片
WeChat_1469878337.jpeg

所有的OC代码全部编译成了Swift的代码,所以说cocoapods导入第三方框架是非常适合Swift开发的

总结

今天给大家介绍了Swift的命名空间以及第三方框架的导入,如果有错误的地方请大家多多指正
我是iOS开发的小菜鸡,希望有天可以变成雄鹰
旅途很长,还需修行

你可能感兴趣的:(Swift命名空间,以及Swift导入第三方框架)