OC底层原理13-应用程序的加载下

前言
上一篇长我们_dyld_objc_notify_register这个方法我们没有细节分析 这节我们我们主要分析一下这个流程

1.dyld链接objc的函数执

我们在objc4-818.2代码里面执行_objc_init函数里面执行_dyld_objc_notify_register(&map_images, load_images, unmap_image);
如图所示:

Xnip2021-07-11_10-32-04.jpg

Xnip2021-07-11_10-33-06.jpg

  • &map_images =_dyld_objc_notify_mapped mapped
  • load_images =_dyld_objc_notify_init init
  • unmap_image =_dyld_objc_notify_unmapped unmapped

而发现在objc4-818.2代码里面找不到_dyld_objc_notify_register这个函数的实现 通过dyld源码发现可以查询到_dyld_objc_notify_register这个函数的实现如下图

Xnip2021-07-11_10-36-12.jpg

_dyld_objc_notify_register的实现有dyld3dyld2两种 我们这里分析的是 dyld2 为什么呢。因为我们设置断点调试发现是走的dyld2

Xnip2021-07-11_19-44-14.jpg

那么这个_dyld_objc_notify_register map_imagesload_images 在什么时候调用的呢

Xnip2021-07-11_19-48-07.jpg

Xnip2021-07-11_19-48-31.jpg

  • map_images = mapped = sNotifyObjCMapped
  • load_images = init = sNotifyObjCInit

sNotifyObjCMappedsNotifyObjCInit在什么时候调用

sNotifyObjCMapped在什么时候调用 我们发现有一个notifyBatchPartial执行

Xnip2021-07-11_19-51-19.jpg

Xnip2021-07-11_19-51-47.jpg

sNotifyObjCInit在什么时候调用呢 我们发现在notifySingle调用

Xnip2021-07-11_20-08-05.jpg

notifySingle在什么时候调用呢 我们发现在recursiveInitialization调用
Xnip2021-07-11_20-09-32.jpg

map_images会调用

Xnip2021-07-11_20-17-37.jpg

会调用 map_images_nolock

Xnip2021-07-11_20-18-20.jpg

load_images的方法调用

Xnip2021-07-11_11-47-25.jpg

prepare_load_methods的方法调用

Xnip2021-07-11_11-50-37.jpg

call_load_methodsload的方法调用 优先[ViewController load]的方法

其次 __attribute__((constructor)) void kcFunc() 调用这个方法

Xnip2021-07-11_11-58-01.jpg

2.dyld to main()函数

Xnip2021-07-11_12-06-17.jpg
最后jmp跳转main()函数

补充

map_images->关键的一些数据

  • 1.类的加载-协议-属性rorw慢速流程-懒加载-非懒加载
  • 2.map_images在什么时候调用
  • 3.load_images()load方法+cxx + main
  • 4.dyld->main
  • 5.上一阶段的考试分析
  • 6.视频 wwdc2017 dyld2 VS dyld3
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享