静态库 (Static Library)
-
分发文件大
-
静态库默认仅讲有用到的类文件
link到Mach-O中(已类文件为最小链接单位) -
ipa包小(为了APP瘦身,尽量将代码放静态库中)
- 静态库中某个目标文件的代码没有被任何地方引用,则这个目标文件不会被链接到可执行文件中去(前提是不要使用
-Objc和-all_load选项,分类代码经常被优化掉,一般都使用-force_load来处理静态库分类加载问题)
- 静态库中某个目标文件的代码没有被任何地方引用,则这个目标文件不会被链接到可执行文件中去(前提是不要使用
-
APP冷启动速度快
- 前提是不使用
动态库拆分搭配动态库懒加载方案 - APP启动流程中有
rebase和bind,多个静态库只需要rebase和bind一次
- 前提是不使用
-
存在符号冲突可能
-
共享
TEXT段- iOS9以前单个Mach-O的TEXT限制60M
- iOS9以后单个Mach-O的TEXT限制500M
-
不需要额外签名验证
-
静态库符号的可见性可以在链接期间被修改
-
文件格式多为
fat格式的静态库文件 -
形式多为
.a与.framework -
静态库不含
bitcode时,引用静态库的目标部署时就不能包含bitcode
动态库 (Dynamic Library)
- 分发文件小
- ipa包大
- 动态库会把整个
lib复制进ipa中
- 动态库会把整个
- APP冷启动速度慢
- APP启动流程中有
rebase和bind,多个动态库只需要多次rebase和bind
- APP启动流程中有
- 需要设置合适的
runpath - 需要动态加载
- 需要签名且需要验证签名
- 会检查
framework的签名,签名中必须包含TeamIdentifier,并且framework和host APP的TeamIdentifier必须一致 - Xcode重签命,保证动态库签名一致性
- 会检查
- 需要导出符号
- 重复的
arch结构 - APP与动态库中重复代码可以共存,不会发生符号冲突
- 因为可执行文件在构建链接阶段,遇到静态库则吸附进来,遇到动态库则打个标记,彼此保持独立性
- 对于来自动态库的符号,编译器会打个标记,交给dyld去加载和链接符号,也就是把链接的过程推迟到了运行时执行。(比如APP使用的是3.0版本SDK,动态库使用的是1.0版本SDK,能正常运行,但是会有风险)
- 连接后需要包含分发大小
- 冷启动过程中,默认会在
main函数之前加载-
默认情况下,过多的动态库会拖慢冷启动速度,可以使用
dlopen和bundle懒加载优化
-
- 文件格式
Mach-O(一个没有main函数的可执行文件) - 动态库不包含
bitcode时,引用动态库的目标部署时可以包含bitcode CocoaPods从v0.36.0开始,可添加关键字use_frameworks!编译成类似Embedded Framework的结构(可以称之为umbrella framework)- 缺点:默认把项目的依赖全部改为动态库(可是使用
use_modular_headers!,也可以在podsepc添加s.static_framework = true规避) CocoaPods执行脚本把动态库嵌入到.app的Framework目录下(相当于在Embedded Binaries加入动态库)
- 缺点:默认把项目的依赖全部改为动态库(可是使用