app的启动过程(三)

这是戴老师发布的第三篇,正经发布的第一篇。看了1天之后我就想说,我要不仍是去卖人参吧,太难了!这之后我要是全学会了我有马上辞职去阿里的冲动。固然了,我除了在学习里面的知识,我还在想1个问题。架构

为何他会我不会?app

这个问题的扯淡程度直逼他的答案的扯淡程度,我以为我不会的缘由是由于很大一段时间我以为学了没用。按照文章的优化方法,咱们那个小破app启动顶多能缩短个几百ms,由于原本app就简单。可是缩短个几百ms对于1个app没用对于技术有用么?这要涉及到学习方法。dom

我本身总结的学习方法是这样的:好比你要学一门新的语言,你要买1本基础书。有人说基础啥的你上网查不就得了?可是别忘了,你没学过你连查啥都不知道。还有就是学基础的时候别查的太深,这个阶段以用为主。等过了这个阶段,开始查漏补缺,进行深刻进阶。这也是我学习戴老师课程的缘由。因此缩短个几百ms,可能用app的人感受不到,可是这个技术不理解,我看我下一章也不用看了。函数

正文开始,app的启动过程学习

咱们首先将app分为冷启动和热启动,热启动顾名思义,人家都热了,说明启动一遍了,可能在后台啥的,这个阶段能作的事不多,咱们不研究。咱们从冷启动开始说,冷启动咱们又分为三个阶段优化

1. main()函数执行前。这个阶段咱们主要有如下几个部分(1)加载可执行二进制文件mach-o文件(昨天的查漏补缺一直就是针对的这个)(2)加载动态库连接器dyld,dyld是个专门用来加载动态连接库的库。执行从d yld开始,dyld从可执行文件的依赖开始,递归加载全部的依赖动态连接库。动态连接库包括iOS用到的全部系统Framework,加载OCruntime用到的libObjc,系统级别的libSystem,例如libdispatch(GCD)和libsystem_blocks(Block),进行 rebase 指针调整和 bind 符号绑定 (3)Objc进行类的注册,肯定方法的惟一性 (4)初始化执行load方法,attribute((constructor)) 修饰的函数,建立C++全局静态变量。spa

好了,这些东西就足够咱们研究一阵子的了。咱们先说一下什么是Mach-o文件,mach-o就是Mach Object。官方给的Mach-o文件很是复杂,里面有啥啥啥的看不懂的东西,就是已经细微到寄存器的东西,我实在研究不通。就只按我本身的理解来讲,Mach-o文件其实就是一些文件的集合:里面有二进制文件,类型为Excutable,里面还有动态库文件dylib,里面还有捆绑包,bundle包,一种特别的动态库,只能在运行时运行。Framework文件,是包含资源或者头文件的静态库或者动态库。那么mach-o文件在哪里看呢,我找了半天就是没找到。后来才知道,通常的framework里面都有.o文件可是你是看不到的,你须要用一个叫MachOView的软件打开它才能看见里面的.o文件不然你看到的可能就是这样的指针

这是百度人脸识别的SDK,反正我是没找到什么.o文件。可是咱们好像换一种方法看不到,能摸到:cdn

这样咱们确实看到它是1个mach-o文件了哈,可是再深刻的我就没有研究了。blog

下面咱们在研究下什么叫rebase指针调整和bind符号绑定。首先咱们肯定一下这个是动做是谁作的。是dyld作的。dyld是什么?动态库链接器。怎么样连接动态库?为何要连接动态库?由于加载了mach-o二进制文件后,动态库是独立的,dyld要将全部动态库绑定起来。mach-o动态库上面要写上要绑定的动态库的指针和数据,用来修正(fix-up),修正有两种类型,一种叫rebasing,一种叫binding。为何要修正呢?听说在iOS4.3之前不须要修正,后来有了ASLR(address space layoutrandomization)的存在,可执行文件和动态连接库在虚拟内存中的加载地址每次启动都不固定,因此须要这2步来修复镜像中的资源指针,来指向正确的地址。 rebase修复的是指向当前镜像内部的资源指针; 而bind指向的是镜像外部的资源指针。 第三点进行类的注册优化起来就很明了,就是咱们尽量减小类的数量,就能够减小加载时间。第四个,初始化执行load方法也很简单就是少些+load()方法,attribute((constructor)) 修饰的函数调用就是1个函数能够在main函数以前调用,有什么做用还不清楚,我没用过,如图:

输出为:

C++全局变量就相似于这种,如图:

2. main()函数执行后。main() 函数执行后的阶段,指的是从 main() 函数到 appDelegate 的 didFinishLaunchingWithOptions方法里首屏渲染相关方法执行完成。这里面要写的东西咱们你们就很熟悉了,通常就是初始化首屏架构,一些第三方的初始化,可是其中咱们应该区分开,哪些是首屏渲染以前应该写的,哪些能够在使用功能的时候才开始。另外关于这个首屏初始化没有1个固定的说法,有些人认为到首页viewDidAppear出现了才算,有的人认为走完了didFinishLaunchingWithOptions就算,看我的理解吧。

相关文章
相关标签/搜索