本文由快学吧个人写作,以任何方式转载请标明原文出处

本文仅介绍库和dyld的一些概念性内容,便利以后的一些dyld加载动态库的内容做铺垫。

一、代码的编译流程

源文件 —> 预编译 —> 编译 —> 汇编 —> 链接 —> 可执行文件

这个流程和下面的解说要刻在骨子里。

(1). 源文件 : 例如OC中的.h.m文件。C++里边的.cpp文件,这种我们写代码的文件叫源文件。

(2). 预编译 : 也叫预处理,是编译之前的处理工作。做的工作是:注释被删去、头文件被打开、宏被替换、条件编译被处理。

(3). 编译 : 对你写的代码进行词法剖析、语法剖析、语义剖析,并且进行恰当的优化。生成.s为后缀的汇编代码文件。

(4). 汇编 : 将编译生成的.s后缀的汇编文件转换成机器能够执行的机器指令,生成.o后缀文件,也便是生成机器指令文件。

(5). 链接 : 将所有的机器指令文件,也便是.o后缀文件,以及需求运用的第三方库经过链接器关联在一同,并生成可执行文件(mach-o格局)。

二、什么是库

1. 库的了解 :

库是一份可执行代码的二进制。能够被操作系统载入内存,并且被辨认。

在链接阶段,会将汇编生成的方针文件(.s文件)与引证的库一同链接,打包生成到可执行文件中。

2. 库的常见分类

1. 静态库 : 例如以.a.lib.framework为后缀的库。

静态库在链接的时分,会被完好的仿制到可执行文件中,当静态库被屡次运用时,就会屡次仿制到内存中,会呈现仿制冗余,形成内存糟蹋。

2. 动态库 : 例如以.framework.so(安卓的动态库文件格局)、.dll为后缀的库。

动态库在链接的时分,不会直接在被调用途进行仿制和被调用,而是在程序运行时才被载入到内存中,以供运用。

3. 静态库和动态库的解析示意图

1. 静态库 :

十六、关于库和dyld的概念

如图所示,假定代码段1和代码段2是同一个项目中的两段代码,并且1和2分处在不同的模块下,可是同时都需求引证静态库中的文件B和文件D。

由于是静态库,所以在1运用的时分,需求将静态库仿制到内存中,再调用B和D。在2运用的时分,又将静态库仿制到内存中,再调用B和D。

2. 动态库

十六、关于库和dyld的概念

如图所示,假定代码段1和代码段2是同一个项目中的两头代码,并且1和2分处在不同的模块下,可是同时都需求引证动态库中的文件B和文件D。

由于是动态库,所以系统会在1运用的时分,将动态库加载到内存中,再调用B和D。在2运用的时分,则不会再进行一次动态库的加载,由于在1调用动态库的时分现已加载了动态库到内存,所以2就会直接运用现已加载到内存中的动态库中的B和D。

4. 动态库和静态库的优缺陷

  1. 静态库:

长处 : 不受外部环境的影响。比方删去了静态库,对可执行文件不会形成影响,由于静态库在链接时就现已打包到可执行文件中了。

缺陷 : 糟蹋内存空间。如果静态库进行了修正,可执行文件也需求重新编译生成。

  1. 动态库:

长处 : 只加载到内存中一次,内存同享,节约内存空间。

缺陷 : 运行时载入会形成性能丢失,并且可执行文件依赖外部环境,一旦动态库进行了修正,可是呈现了错误,则会导致程序呈现问题。

5. 什么是framework

framework是Cocoa/Cocoa Touch程序中运用的一种资源打包方式。能够将代码文件、头文件、滋源文件、阐明文档等会集在一同

  • 静态的framework :

一般我们树立的.framework,打包成sdk给别人用的,都是静态的,虽然在xcode中创建的时分,Mach-O Type 默许是 Dynamic Library,树立的时分默许是动态的。

一般静态的framework,资源打包进了framework是读取不了的。静态的framework会被编译进可执行文件中。

一般我们运用的第三方库都是静态的framework。

  • 动态的framework :

系统供给的framework是动态的。Cocoa/Cocoa Touch就供给了大量的动态framework。例如 : Foundation.framework、UIKit.framework等。

动态的framework能够在工程中的framework文件夹下看到,并且是能够读取其中的资源的。

三、什么是dyld

英文全称 : the dynamic link editor

中文全称 : 苹果动态链接器

dyld是苹果操作系统的非常重要的组成部分。在app被打包生成可执行文件mach-o之后,dyld会对可执行文件进行链接各种库和加载主程序。

如下图所示 :

十六、关于库和dyld的概念

  1. 加载libSystem。
  2. 注册会掉函数。
  3. 映射、加载库的镜像
  4. 链接库的内容。
  5. 调用main函数。