初探dyld动态链接器流程对iOS又精进了一步

7,186 阅读3分钟

前言:作为一个开发者,如果你熟悉很多语言的开发,你会发现大部分语言的一个共同点,main函数。我们都是从main函数开始,去关注程序的编写、编译和执行过程。main函数之前,系统有没有做一些其他的工作,做了哪些工作呢,一起来看看?

一、应用启动分析

1、程序从编写到执行的过程

1、代码怎么加载到内存?
2、静态库、动态库怎么加载到内存?
3、objc_init -> objc 在哪里执行的?

我们可以想一下以上的过程是怎么发生的,各个环节都是怎么加载到内存的?

2、静态库和动态库

我们经常在项目中使用静态库和动态库,其中系统提供的UIKit,Foundation库,WebKit库等等,这些是动态库,比如我们经常使用的自定义的静态Framework,.a文件,就是属于静态库。那么,静态库和动态库是怎么区分的?

●动态库形式:.dylib和.framework
●静态库形式:.a和.framework

如上图所示,我们分析:
1、静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝
2、动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存
但是,系统的动态库怎么加载到内存呢?通过什么方式?这里就用到了一个工具dyld动态链接器。

3、动态链接器

3.1 动态链接器的工作过程

上面是dyld的加载工作流程图,通过它主要进行了动态库的注册和动态库的加载过程。

二、dyld过程初探

●通过上面原理的整体分析后,我们接下来就进行应用程序代码执行逻辑的分析

在main函数的入口位置,加上断点,运行后程序停在断点位置,经过堆栈打印(bt为lldb堆栈打印命令),发现程序是崩溃在了lldb中,这里我们并不能获取更多信息去跟踪。
于是,我们通过编程经验,想到了在程序执行main函数之前,会提前执行load函数的加载,那么就做一下尝试,在ViewController中假如load函数,并添加断点,运行程序。

结果很顺利,我们断点停在了ViewController的load方法,通过堆栈打印,发现了关于dyld的一系列函数过程。下面就引出我们探究的主题:dyld(动态链接器),我们的函数追踪,也将按照这样一个顺序去进行!

1、dyld简介

dyld(the dynamic link editor)是苹果的动态链接器,是苹果操作系统一个重要组成部分,在系统内核做好程序准备工作之后,交由dyld负责余下的工作。而且它是开源的,任何人可以通过苹果官网下载它的源码来阅读理解它的运作方式,了解系统加载动态库的细节。

2、dyld的源码

苹果官方 dyld库 下载地址

这里我们选择最新的版本进行研究,技术嘛,总要与时俱进,下载完这些,先不急,先来一个苹果的官方视频介绍,关于dyld2,到dyld3过程的更新、特性,然后我们在下一章介绍 dyld 的探究过程。

3、苹果官方关于dyld的介绍视频

App Startup Time: Past, Present, and Future https://developer.apple.com/videos/play/wwdc2017/413/

三、总结

我们这里介绍了应用启动过程的大概过程分析,主要有:
1、动态库与静态库的概念和理解
2、dyld的概念和链接过程解析
3、我们是如何知道程序是在main函数之前进入了dyld
关于dyld的详细执行过程,下一节单独讲解!

链接:iOS应用启动流程分析之dyld源码解析