美文网首页IOS网友们的篇章iOS Developer
Swift命名空间,以及Swift导入第三方框架

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

作者: iOScoderZZJ | 来源:发表于2016-07-30 15:52 被阅读1881次

    前言

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

    在 Swift 中,由于可以使用命名空间了,即使是名字相同的类型,只要是来自不同的命名空间的话,都是可以和平共处的。和 C# 这样的显式在文件中指定命名空间的做法不同,Swift 的命名空间是基于 module 而不是在代码中显式地指明,每个 module 代表了 Swift 中的一个命名空间。也就是说,同一个 target 里的类型名称还是不能相同的。
    <a href="http://swifter.tips/namespace/?utm_source=tuicool&utm_medium=referral">原文链接</a>(侵权删)

    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修改命名空间

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

    WeChat_1469869899.jpeg

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

    WeChat_1469870116.jpeg

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

    1.2动态加载命名空间

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

    WeChat_1469870535.jpeg

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

    WeChat_1469870597.jpeg

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

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

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

    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用途

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

            //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,如下图

    WeChat_1469876625.jpeg

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

    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击跳进去看看里面,如下图 WeChat_1469878337.jpeg

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

    总结

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

    相关文章

      网友评论

      • nicodeng:怎么样能全局import afnetworking 而不需要使用了就import
        nicodeng:@iOScoderZZJ 在swift中可以直接在桥接文件里面@import,就可以了
        iOScoderZZJ:@nicodeng 很久不研究swift了,按照原来这种公共库的引用放在pch中,在swift中是否试用我不太清楚了

      本文标题:Swift命名空间,以及Swift导入第三方框架

      本文链接:https://www.haomeiwen.com/subject/nfltsttx.html