iOS编译与加载流程

一、编译原理:

一般编程语言可分为编译型语言和直译型语言,我们常用的Objective-C就属于编译行语言(这边就先忽略直译型语言了)。

OC编译的执行过程大概分为:

1、把源文件(.h .m .cpp),先进行预编译(把一些宏定义进行预处理)操作

2、把OC高级代码编译成汇编底层代码

3、链接.a .lib 等静态库文件,依赖UIKit,写入可执行文件

4、生成可执行文件

由于编译高级语言会生成汇编代码,汇编代码在CPU调度的时候执行速度是最快的,所以执行效率最高。

接下来直接用代码看一下效果:


 LGperson *p = [LGperson alloc];

 [p instanceMethod];

 [LGperson classMethod];

 NSLog(@"hello world!");

首先创建一个LGperson的NSObject文件,添加一个实例方法(instanceMethod)和类方法(classMethod),在main.m里添加以上代码,然后进行编译操作。


image.png

会出现一个LGTest的可执行文件,打开执行


image.png

通过这个可执行文件,可以看出来这样一个加载流程,在程序还没运行,只是在编译的时候,hello world就被打印出来了。

二、库文件

在讲编译和加载的时候,不得不提一个最重要的东西,就是库文件,一般库文件可分为静态库和动态库,总结了一下他们的特点。

静态库:常用.a .lib,在链接阶段会将汇编生成的目标文件(.o)与引用的库一起打包生成可执行文件。

动态库:常用.so .framework .dl等,编译的时候不会用,运行的时候才调用,减少打包app的体积,共享内存,热更新(更新动态库),由于动态库可以进行更新操作,容易被注入恶意代码,就会变得不稳定不安全。常用动态库有UIKit、libsystems、libobjc、CFFoundation框架等。

三、APP启动流程

APP启动的底层原理:

_dyld_objc_notify_register(&map_images, load_images, unmap_image);

1、加载libsystems,通过runtime向dylb(动态链接器)注册回调函数_dyld_objc_notify_register(dyld提供,只能被runtime使用)

2、加载images库文件。

3、执行map_images(处理由dyld映射的库文件)和load_images(加载所有+load方法)

4、调用main函数

系统库通过dyld管理,加入runtime,通过dyld赋予静态库一个运行时的功能。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容