静态库 (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
加入动态库)
- 缺点:默认把项目的依赖全部改为动态库(可是使用