第十三章:鹊桥会 —— OC 与 Swift 的混编

13.1 两个世界的桥梁

虽然 Swift 喊着要杀掉 OC,但 Apple 还是留了一手:完美的互操作性(Interoperability)。 你可以在同一个项目里,左边是 .swift,右边是 .m

13.2 这一侧:Swift 调用 OC

只要你在 Bridging-Header.h 里把 OC 的头文件 #import 进去,Swift 就能看见它们。 而且 Swift 会自动把 OC 的 API “翻译”得更 Swift 一点:

  • initWithString: -> init(string:)
  • NS_ENUM -> Swift Enum

这是最舒服的方向。Swift 就像吃自助餐一样享用现有的海量 OC 库。

13.3 那一侧:OC 调用 Swift

这就有点难受了。 首先,Swift 的类必须继承自 NSObject。 其次,你想暴露给 OC 的属性和方法前,必须加上 @objc 关键字。 只有这样,Swift 才会为它们生成动态的派发表,OC 才能通过 Runtime 找到它们。

13.4 Nullability 的救赎

OC 最初是没有 Optional 的概念的。 为了让 Swift 知道 OC 的返回值到底会不会是 nil,OC 后来引入了标注:

  • nonnull: 绝非空。
  • nullable: 可能是空。
  • NS_ASSUME_NONNULL_BEGIN / END: 宏包围,省得一个个写。

如果没写这些,Swift 会把 OC 的对象识别为 Implicitly Unwrapped Optional (Type!),这是一个充满危险的信号。一旦它是空,你访问它,就崩了。

13.5 总结

混编是目前大型 App 的常态(尤其是国内大厂)。 但是混编会带来编译时间的直线上升,以及调试时的各种莫名其妙的报错。 如果可以,尽量保持模块间的纯净。不要在同一个模块里纠缠不清。

使用 Hugo 构建
主题 StackJimmy 设计