iOS 底层原理之—dyld 与 objc 的关联
前言
在dyld
加载过程中,我们知道会调用_objc_init
方法,那么在_objc_init
方法中究竟做了什么呢?我们来探究下。
_objc_init方法
_objc_init方法实现
从_objc_init
实现中我们分析下该方法主要做了什么
environ_init()
该方法主要是读取运行时的环境变量,我们可以通过设置DYLD_PRINT_STATISTICS = YES
来打印APP启动到main()函数之前的时长,进而可以进行APP启动优化。具体的environ_init()简介可参考博客iOS-底层原理 16:dyld与objc的关联中有关nviron_init()
部分的介绍
tls_init()
主要用于关于线程key的绑定,比如每线程数据的析构函数。
static_init()
主要是C++静态构造函数
runtime_init()
主要是运行时的初始化,主要分为两部分:分类初始化
和类的表初始化
exception_init()
初始化libobjc异常处理
cache_init()
主要是缓存初始化
_imp_implementationWithBlock_init()
主要用来启动机制回调
dyld与objc关联
_dyld_objc_notify_register(&map_images, load_images, unmap_image)
主要是dyld
注册 实际代码实现
从上文正中我们可以看出
-
mapped
即map_images
-
init
即load_images
-
unmapped
即unmap_image
map_images()函数分析
从map_images
函数中我们发现map_images_nolock函数
是重点,我们进入map_images_nolock
函数
map_images_nolock
我们查看代码实现
从截图中我们可以看出_read_images
是我们要重点研究的方法
_read_images函数分析
是否是第一次加载
修复预编译时@selector
的错乱问题
错误类处理,通过readClass
读取出来类的信息
重新设置映射镜像
消息处理
类中如果有协议,读取协议
映射协议
加载分类
注意
在分类处理中主要是通过load_categories_nolock
处理,我们进入load_categories_nolock
函数中
load_categories_nolock
函数
从load_categories_nolock
函数实现中,我们可以看到该函数将类
、实例方法
、协议
、属性
、类方法
等再次链接了一次。
非懒加载类处理
处理没有使用的类
dyld与objc关联总结
-
dyld_start
调用_objc_init
来初始化,_objc_init
中通过dyld
调用_dyld_objc_notify_register
函数,传入map_images
跟load_images
这两个参数来处理 -
map_images
通过map_images_nolock
函数调用_read_images
函数 -
在
_read_images
函数中处理类信息、属性、协议、分类等
-
当一切准备妥当,则再次返回
dyld_start
中,此时dyld
跟objc
关联了起来
资料推荐
如果你正在跳槽或者正准备跳槽不妨动动小手,添加一下咱们的交流群1012951431来获取一份详细的大厂面试资料为你的跳槽多添一份保障。