dyld和objc关联

2020-10-14  本文已影响0人  北京_小海

上一篇我们讲述了 dyld 的加载流程 这篇文章我们来搞清楚dyld和objc的关联。

首先看一下objc4-781官方源码_objc_init方法

environ_init(); //环境变量的读取初始化 

tls_init(); //自动释放池、runloop线程相关 

static_init(); //运行C ++静态构造函数 

runtime_init(); //新增的。runtime运行时环境初始化 

exception_init(); //异常捕获初始化 

cache_init(); //缓存条件初始化

 _imp_implementationWithBlock_init(); //启动回调机制

下面着重分析下_dyld_objc_notify_register 

_dyld_objc_notify_register 这个方法是跨库执行的,在苹果开源的 dyld 源码里面可以找到,然后看到调用了 dyld::registerObjCNotifiers 这个方法:

load_images

接下来我们分析一下registerObjCNotifiers方法的第二个参数init,(也就是_dyld_objc_notify_register方法中的load_images参数)方法里面有sNotifyObjCInit = init;这个赋值语句,接下来我们在dyld源码中全局搜索一下sNotifyObjCInit,会发现在notifySingle方法中有sNotifyObjCInit的调用:

所以在 ObjC 中 _objc_init 方法里调用的 _dyld_objc_notify_register 方法终于在 dyld 源码中找到其真正调用的地方,终于找到了它们真正的关联关系了。

map_images

那么_dyld_objc_notify_register方法中的map_images参数呢?接下来我们继续找registerObjCNotifiers方法中的sNotifyObjCMapped = mapped;这一赋值语句,在dyld源码中全局搜索一下sNotifyObjCMapped,同样会发现在notifyBatchPartial方法中有sNotifyObjCMapped的调用:

所以说 ObjC 中 _objc_init 方法的调用时离不开 dyld 的,它们之间有着紧密的联系。

我们还可以继续探索一下 map_images, 进入到 objc_781 源码,全局搜索相关的函数调用 map_images ,我们能进入相关的函数调用过程:

再进入到 map_images_nolock 方法中,我们能发现其中有很多加载相关类的信息 _read_images:

我们知道,map_images这个函数的主要功能就是为了映射相关的类信息,所以此处才是我们研究的重点,接着进入到相关的类方法的定义_read_images方法,顺着源码分析我们能得到很多关于类的信息:

• 1: 条件控制进⾏⼀次的加载

• 2: 修复预编译阶段的 `@selector` 的混乱问题

• 3: 错误混乱的类处理

• 4:修复重映射⼀些没有被镜像⽂件加载进来的 类 

• 5: 修复⼀些消息! 

• 6: 当我们类⾥⾯有协议的时候 : readProtocol 

• 7: 修复没有被加载的协议

• 8: 分类处理

• 9: 类的加载处理

• 10 : 没有被处理的类 优化那些被侵犯的类

下篇文章继续讲解~~~

上一篇下一篇

猜你喜欢

热点阅读