不同Mach-O如何Load
根据苹果的WWDC视频介绍,App在运行时采用COW(Copy Of Write)策略 会将需要运行的程序先拷贝一份,然后依次加载其需要dylib
这种机制就造成不同的Mach-O会有不同的执行策略
Static Mach-O
经过nm指令分析,对于 lib.a 的 Static Mach-O 并不是可运行的二进制文件,而是一组.o文件的压缩包,并且不会进行Duplicated Symbols检查
其会随着主程序启动一起启动,原因是其最终进入了主程序的Mach-O(会在后续进行详细分析)
Dynamic Mach-O
对于Framework其本身已经和主程序没有任何区别,理论上只要不存在Undefined Symbols 其是可以单独运行的Mach-O文件,并且不存在重复的符号
其会晚于主程序启动,并且其启动的过程是可控,并且和主程序不是一个Mach-O(后续会详细分析)
StaticLib 和 Framework 的区别
StaticLib 被称为静态库,Framework可以被称为动态库,但是其也可以作为静态库来编译(后续会有分析)除去编译命令不同,Framework对比StaticLib还具有以下特点
- 自身可以携带头文件,不用像StaticLib配置头文件搜索目录
- 自身可以携带资源文件
- 自身可以进行头文件的权限处理,如Public Project Private
Framework之所以好,是因为其把 HeaderFile Resources ExecutableFile 放在了一起,为模块化提供了很好的基础
Function | 基于技术 |
---|---|
Header File | LLVM中的 modulemap 技术 |
Resources | Apple的dlopen函数可以运行时读取 |
ExecutableFile | Apple的Mach-O文件 |
Framework 的延迟加载
Framework与静态库最大的不同是可以做到延迟加载,根据苹果的WWDC视频介绍在App启动后,会依次对动态库进行加载,但是也可以通过配置控制在第一次使用到时进行加载
添加完Framework默认是不延迟加载的,会严重影响App启动速度,设置延迟加载的方式是 在Linked Framework and Libraries中将右侧的选项至为Optional
这里有个经验是 如果Target.app的二进制可执行文件过大,可能会不通过苹果的审核,使用Framework(Dynamic Mach-O)会减小App的可执行文件体积