Swift

Swift 编程思路的变化

今天看到这篇文章,才发现之前那次尝试着用 Swift 写代码时犯了一个多大的错误。

上次是在做优优育儿时,有一个新功能非常简单,就是一个单纯的列表页,所以尝试着用 Swift 进行了实现。而我当时正是像文章中写的那样,只是把之前 Objective-C 的写法按照 Swift 的语法进行了变化,然后相信了 Xcode 的代码更正提示,结果虽然可以正常运行,但代码里全是 exclamation mark。

阅读了这个系列的文章,发现 Swift 的确是个现代化的语言。虽然凭借传统语言的知识可以很容易地入手,但它所带来的不仅仅是语法的改变,更多的是编程思路的变化。

下面我将分别展示三段代码,功能是从 JSON 串中得到一个 Article 对象的数组。第一段是用 Objective-C 编写的代码,这也是我写这种功能的标准形式。第二段是按照传统思路编写的 Swift 代码,是应该避免的。第三段是用正确的思路编写的 Swift 代码。

Swift 与 Objective-C 混编

Swift 这门新兴的编程语言,自从 WWDC 2014 被发布以来不断被完善,并获得了越来越多苹果开发者的认可。WWDC 2015 时 2.0 版本的发布以及开源,让我们看到了 Swift 的不断成熟,苹果也在提倡开发者们向 Swift 转移。

我很早就阅读了 Swift 的相关内容,并且感觉它是一个很不错的开发语言。它具有一些现代脚本语言的特征,更重要的是跟我早先常用的 Pascal 语言在很多地方十分相近,感觉很亲切。虽然如此,实际在工作中还并未引进 Swift,我和我的团队依然在用 Objective-C 进行 iOS 软件的开发。

今天突然想在开发新功能时试一把 Swift,于是研究了一下 Swift 和 Objective-C 的混编,在原有 Objective-C 工程中引入了 Swift。

Swift 代码调用 Objective-C 代码

在现有 Objective-C 工程中,新建一个 Cocoa Touch Class,新建时选择 Language 为 Swift,会弹出对话框提示是否需要创建 Bridging Header:
Create Bridging Header

创建后工程中会新建一个名为 ProjectName-Bridging-Header.h 的头文件。编辑这个头文件,Swift 代码需要调用的 Objective-C 头文件,都在这个文件中 import 即可:

ProjectName-Bridging-Header.h
1
2
3
4
5
6
7
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "BaseViewController.h"
#import "APIHandler.h"
#import <YYModel.h>
#import <MJRefresh.h>

另外,可以在工程属性的 Build Settings 中,可以找到 Objective-C Bridging Header 项,其中已自动填入了这个 ProjectName-Bridging-Header.h 的路径。

Objective-C 代码调用 Swift 代码

在需要调用 Swift 代码的 Objective-C 文件头部,写入:

1
#import “ProductModuleName-Swift.h”

即可,然后就能调用工程中 所有 的 Swift 源码,并不需要单独指定需要调用哪一个。
这个 ProductModuleName,默认就是工程名称,如”YouYouYuEr-Swift.h”。可以在工程属性的 Build Settings 中,找到 Product Module Name 项查看。

这个头文件的全名,也可在工程属性的 Build Settings 中,找到 Objective-C Generated Interface Header Name 项查看,可以看到它的值为 $(SWIFT_MODULE_NAME)-Swift.h。(可见上一小节第 2 张图)

但注意,这个文件在工程中 并不 实际存在。因为就像刚才所说,import 这个文件后能调用工程中 所有 的 swift 源码,所以就不需要由开发者再去编辑这个文件,来告知编译器需要引用哪些 .swift 文件。而反过来则不同,Swift 调用 Objective-C 需要告知编译器需要调用哪些 Obejctive-C 文件,所以需要一个 ProjectName-Bridging-Header.h 供开发者去编辑。

总结

可以看到,Build Settings 中的 Objective-C Bridging HeaderObjective-C Generated Interface Header Name 两项,是 Swift 与 Objective-C 混编的关键,分别为一种语言引用另一种语言提供了桥梁。