概述
随着Xcode 11、Swift 5.0的发布,Swift目前已经实现了ABI稳定及模块稳定,并且Swift runtime
和标准库已经植入系统中,而且苹果新出文档都用Swift,Sample Code也是Swift,可以看出Swift是苹果扶持与研发的重点方向。
对于新App来说,可以直接用纯Swift进行开发,而对于老App来说,绝大部分以前都是用OC开发的,因此Swift/OC混编是一个必然面临的问题。
ObjC和Swift混编
OC/Swift
调用 Swift
,最终通过 Swift Module
进行,而 Swift
调用 OC
时,则是通过 Clang Module
,当然也可以通过 Clang Module
进行 OC 对 OC 的调用。
同一工程内的混编
宿主工程利用桥接文件(Bridging-Header.h)进行混编
Swift访问Obje-C
只需要在桥接文件中(Bridging-Header.h
)导入需要暴露给Swift模块的Objective-C类,即可在Swift中访问相应Objective-C的类和方法Objective-C访问Swift
在Objective-C类中导入ProductName-Swift.h
,即可访问Swift中暴露给Objective-C的类和方法
利用cocoapods包管理工具,进行二/三方库混编
Swift访问Obj-C
用Swift Module系统,需要用到的Objective-C类用import xxx
进行引用,即可在Swift中访问相应的Objective-c的类和方法Objective-C访问Swift
在Objective-c类中导入ProductName-Swift.h
,即可访问Swift中暴露给Objective-C的类和方法
Module系统
LLVM Module系统
苹果在 2012 年 11 月提出 LLVM
的 Module
系统,简单讲就是用树形的结构化的描述来取代以往 #include
,例如传统的#include
现在变成 import std.io
意义:
- 语义上完整描述了一个框架的作用
- 提高编译时的可扩展性,同一模块只需编译或导入一次,避免了头文件的多次引用、解析
- 减少碎片化,每个模块只处理一次,环境的变化不会导致不一致
modulemap文件
modulemap
文件就是对一个框架,一个库的所有文件的结构化描述。默认文件名是module.modulemap
Swift Module
SwiftModule 可以将 Swift 解析后生成对应的 modulemap 和 umbrella.h 文件,SwiftModule 增加对编译器版本的依赖,编译产物与编译器 和 Swift 版本有关。如果想要实现 Swift 和 Objective-C 的互相访问,需要 Objective-C 库,以及对应的 umbrella.h 和 modulemap 支持。其中动态库 framework 是 Xcode 支持配置并生成 header,静态库 .a 需要自己编写对应的 umbrella.h 和 modulemap。即库之间无论何种语言实现,均需要封装为 LLVM Module
来相互访问。
Cocoapods配置
use_ modular_ headers! 配置将三方库构建成静态库,或者 use_frameworks! 配置将三方库构建成动态库时,在编译产物中都会生成一个 modulemap 和 module umbrella.h 文件
use_ modular_ headers!
是 Cocoapods 1.5.0 引入的配置,目的是为了满足 Xcode 9 以后支持的 Swift Static Libraries ,将 Swift Pods 构建成为静态库
- 如果你的 Swift Pod 依赖于 Objective-C,那么你需要为这个 Objective-C 库启用 modular_headers
- 对于 pod 开发者可以在 podtargetxcconfig 内添加 ’DEFINES_MODULE’=>‘YES’,对于使用者在 podfile 内添加
use _modular _headers!
- 在 podspec 中通过 modular_headers => true 配置特定的 pod
参考
Swift和Objective-C混编在有赞移动的实践
从预编译的角度理解Swift与Objective-C及混编机制
Swift与Objective-C混编时,我们是如何将编译时间优化了35%
一方:(一方包,一方库),一般指的是本项目或者本工程中的类和方法、接口等。
二方:(二方包,二方库),一般指的是公司内部的依赖库,公司内部其他项目发布的jar包,如公司项目平台的核心依赖包。
三方:(三方包,三方库),一般指的是外部的开源库或开源项目贡献的jar, 比如apache、google、Ali等发布的依赖