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