10、应用程序的加载流程

2020-10-09  本文已影响0人  ChenL

一、编译过程

源文件.h/.m /.cpp -> 预编译 -> 编译 ->汇编 -> 链接(动态库.a/.lib/.framwork)- 可执行文件

源文件:载入.h、.m、.cpp等文件
预处理:替换宏,删除注释,展开头文件,产生.i文件
编译:将.i文件转换为汇编语言,产生.s文件
汇编:将汇编文件转换为机器码文件,产生.o文件
链接:对.o文件中引用其他库的地方进行引用,生成最后的可执行文件

1.png
静态库:在链接阶段,会将汇编生成的目标程序与引用的库一起链接打包到可执行文件当中。此时静态库就不会在改变了,因为它是编译时 被copy一份,复制到目标程序里
动态库:程序 编译时并不会链接到目标程序 中,目标程序只会存储指向动态的引用,在程序 运行时才载入

二、动态链接器(dyld)

在App被编译打包成可执行文件格式的Mach-O文件后,交给dyld负责连接,加载程序。

APP启动 -> 加载libSystem ->Runtime向注册回调函数 ->加载新image -> 执行map_images Load_imags** ->调用main函数

2.png 3.png

三、dyld流程分析

dyld流程分析 ->dyld_start ->dyldbootstrap::start ->dyld::_main->👇

条件准备:环境、平台、版本、路径、主机信息;
mapShareCache共享缓存加载;
instantiateFromLoadedImage实例化主程序
loadInsertedDylib加载插入的动态库
link 主程序
link 插入的动态库
weakBind 弱引用绑定主程序
initializeMainExecutable 初始化 👇
notifyMonitoringDyldMain 通知dyld可以进入main()函数

initializeMainExecutable 初始化
sMainExecutable ->runInitializers 主程序开始初始化
or
runInitializersImages开始初始化 -> processInitializers 初始化准备 -> recursiveInitialization 递归初始化👇

context.notifySingle 单个通知注入
- sNofityObjCinit调用
doInitialization 调用init方法
-registerObjCNotifiers 注册回调函数
-_dyld_objc_notify_register
- sNofityObjCinit调用
context.notifySingle 通知初始化完成

4.png
上一篇 下一篇

猜你喜欢

热点阅读