背景:组件大量使用module的方式引入到工程和管理组件中,其中的一些概念需要彻底搞清楚。
一、Modules的意义
1、@import是iOS7之后的新特性语法:Modules(模块导入)或者"语义引入"。Moudles可以看成是可执行framework的集合,比#import更加高效和快捷。
2、Enable Modules是默认打开的,在Target->YourApp->Build Setting->搜索Modules, 可以看到Enable Modules默认是YES,Link Frameworks Automatically也是默认打开的。这样,编译的时候自动把可能的地方换成modules的写法去编译。从而减少大量#import引入头文件的繁杂步骤。
3、@import的一个优势是开发者不需要手动将framework添加到project settings里面,它是自动完成的。使用Modules的形式,可以使用@import MapKit;还可以只加载framework里面的子submodules,比如:@import MapKit.MKAnnotation;
二、在CocoaPods中使用
1、在Podfile中
Podfile默认使用静态库use_frameworks!,添加use_frameworks!,表示Pod使用动态库,Pod/Products里都是动态库,也就是.framework文件。
2、不添加use_frameworks!,表示Pod使用静态库,Pod/Products里都是静态库,也就是.a文件。
3、在使用静态库时,有的Pod引用的库不支持module怎么处理?
可以使用
use_modular_headers!替换use_frameworks!,让所有的Pod支持静态库。
也可以对某个不支持静态库的Pod后面添加:modular_headers => true来使其支持module。
pod 'SSZipArchive', :modular_headers => true
此外,使用use_modular_headers!属性时,可以使用以下方法从模块化标头中排除特定Pod:
pod 'SSZipArchive', :modular_headers => false
4、它允许你将不同的frameworks合并成一个framework,输出部分头文件。
三、Module map
Module map 指明了 framework 中的头文件逻辑结构应该如何映射为模块。 Xcode 创建 framework时自动创建的 module map 文件,会发现在 Modules 文件夹下有一个 module.modulemap 文件,内容如下:
module TYTUIKit {
umbrella header "TYTUIKit-umbrella.h"
export *
module * { export * }
}
module TYTUIKit.Swift {
header "/Users/zhanyingzhu/Library/Developer/Xcode/DerivedData/MBTytOne-fegdtrcbgueaumgplarovkssadbq/Build/Products/Debug-iphoneos/TYTUIKit/Swift Compatibility Header/TYTUIKit-Swift.h"
requires objc
}
framework module XXXX定义了一个 framework 语义的模块umbrella header "XXXX.h"说明把 XXXX.h 文件作为模块的 unbrella header,伞头文件相当于模块中所有公共头文件的一个集合,方便使用者导入。export *将所有子模块中的符号进行重导出到主模块中module * { export * }定义子模块,这里为 * 则是为 umbrella header 中的每个头文件都创建一个子模块。
理解 Clang Module 和 Module Map 语法
四、常见问题
Q:可以在runtime时加载动态库吗?
A:不可以(除非你不想上AppStore)。苹果不允许在审核后更改app的行为,类似于热修复.
Q: 可以用Swift创建静态库吗?
A:在Xcode9后,可以。CocoaPods 1.5.0也支持Swift Static Framework.
Q:我可以使用多少动态库?有限制吗?
A:我们建议将动态库控制在一定范围内。虽然有可能创建很多的动态库,但是建议尽量不要创建太多的动态库,而使用静态库。
Q: Podfile使用静态库时出现报错[!] The following Swift pods cannot yet be integrated as static libraries:,如何解决?
A:pod install 时的错误信息提示我们应该使用use_modular_headers!来让整个项目支持静态库,或者对单个Pod使用:modular_headers => true