iOS app启动过程

dyld 的全称是 the dynamic link editor(动态链接器)。它是 macOS 和 iOS 操作系统中的一个核心组件,负责准备一个可执行文件(Mach-O 文件)及其所需的库,以便它能够运行。

你可以把 dyld 想象成一个非常专业的“舞台经理”,而你的程序是“主演”。在“主演”上台表演之前,“舞台经理”需要完成以下工作:

dyld 的具体职责:

1. 加载程序本身:首先,dyld 会读取 Mach-O 文件,分析其结构,为程序的代码和数据段在内存中分配空间。

2. 递归加载依赖的动态库(dylibs):

  · 你的程序几乎肯定会使用系统库(如 Foundation, UIKit, AppKit)或第三方库。

  · dyld 会查看 Mach-O 文件中的“加载命令”(Load Commands),找到所有它依赖的动态库的路径(例如 /usr/lib/libSystem.B.dylib)。

  · 然后,dyld 会去这些路径(首先在缓存中查找)加载每一个动态库。

  · 但每个动态库本身也可能依赖其他库,所以 dyld 需要递归地加载所有这些依赖项,直到整个“依赖树”都被加载到内存中。

3. 符号绑定(Binding):

  · 你的程序中调用 printf 函数时,在编译后,这条指令只是一个对“printf”这个符号的引用,并不知道 printf 函数在内存中的具体地址。

  · dyld 的工作就是找到 printf 函数在哪个库(比如 libSystem.B.dylib)中,以及它被加载到内存中的哪个地址,然后将你程序中的那个引用替换成真实的内存地址。这个过程就是符号绑定。

4. 运行初始化例程:

  · 在所有库加载和符号绑定完成后,dyld 会开始执行一些初始化代码。例如,C++ 的全局静态对象构造函数就是在这一步被调用的。

5. 跳转到主程序入口:

  · 当所有准备工作就绪后,dyld 的最后一项任务就是跳转到程序的入口点,通常是 main 函数,这时你的程序代码才真正开始执行。

总结一下你描述的启动流程:

1. 内核操作:你双击程序图标,内核(操作系统核心)将程序的 Mach-O 文件映射到内存中。

2. 启动 dyld:内核检查 Mach-O 文件,找到其中记录的 dyld 的路径(例如 /usr/lib/dyld)。

3. dyld 接管:内核将控制权交给 dyld。

4. dyld 进行“舞台准备”:dyld 开始上述的加载、链接、初始化等一系列复杂工作。

5. 程序开始执行:dyld 完成所有工作后,调用 main 函数,程序启动完成。

所以,dyld 是连接你的静态程序和运行时动态环境的桥梁,是保证你的应用能够顺利运行不可或缺的组件。现代 dyld 还有很多优化,比如共享缓存,可以极大地加快应用的启动速度。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容