iOS开发iOS开发技术iOS进阶

iOS编译与app启动

2017-03-09  本文已影响2095人  alvin_wang

iOS编译

当一个xcode工程build之后一般会执行如下几个步骤:

iOS编译采用Clang作为编译器前端,LLVM作为编译器后端。流程如下

编译过程.png

Clang的任务:预处理、词法分析、语法分析、语义分析、静态分析、生成中间代码。
预处理:以#开头的代码预处理。包括引入的头文件和自定义宏。
词法分析:每一个.m源文件的声明和定义从string转化为特殊的标记流。
语法分析:将标记流解析成一颗抽象语法树( abstract syntax tree-AST)。
静态分析:包含类型检查和其他检查。
中间代码生成:生成LLVM代码。

Clang过程.png

LLVM的任务:将代码进行优化并产生汇编代码。
汇编器:将可读的汇编代码转换为机器代码,最终创建一个目标对象.o文件。
链接器的任务:把目标文件和库相连,最终输出可运行文件:a.out。

Mach-O

Mach-O是针对不同运行时可执行文件的类型。
文件类型:

Mach-O镜像文件
所有Mach-O(可使用MachOView工具查看)都包含:__TEXT, __DATA, __LINKEDIT:

app启动

当用户点击一个app,app从启动到打开第一个页面的时间 t = t1 + t2,其中t1 = 系统dylib和自身app可执行文件(app中所有.o文件的集合)的加载,t2为main函数到appdelegate中的- (BOOL)Application:(UIApplication *)Application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法执行结束这段时间。

app启动后,先加载可执行文件,再使用dyld(动态链接器)动态递归加载dylib(系统的framework,oc runtime的libobjc,系统级别的libSystem)。由于dylib是共享的,所以可以减少app包的体积。

dylib加载过程

  1. load dylibs image
  2. Rebase image
  3. Bind image
  4. Objc setup
  5. initializers

Rebase/Bind是用来修复image中的资源指针,使其指向正确的地址(因为iamge是加载在虚拟内存中(ASLR))

Objc setup工作

initializers
前面三步是静态调整,修改__DATA segment内容。这里开始动态调整,开始在堆栈中写入内容。

main()之前的加载时间

它可以通过以下方式来显示。

launch time.png

结果如下:


pre-main time.png

main()调用之后的加载时间

  1. 准备阶段,主要是图片的解码
  2. 布局阶段,-(void)layoutSubViews()
  3. 绘制阶段,-(void)drawRect:(CGRect)rect
  4. 启动阶段必要服务的启动、必要数据的创建和读取。

优化启动时间

参考链接

趣探 Mach-O:文件格式分析
优化 App 的启动时间
Mach-O 可执行文件
编译器

上一篇 下一篇

猜你喜欢

热点阅读