在上篇文章 dyld 了流程分析 中我们大概了解了 程序启动 到main函数之前dyld做了哪些事情
dyld 流程之第8步 【执行初始化方法】 我们也做了具体分析,通过堆栈加源码查看 了解到recursiveInitialization
是一个递归函数,初始化各种链接库,库的优先级最高的为libSystem
初始化, libSystem_initializer(libSystem.B.dylib
) --> _os_object_init(libdispatch.dylib
) --> _objc_init(libobjc.A.dylib
) 而 _objc_init
函数的调用 里面发现了 _dyld_objc_notify_register
, dyld
又发现了其接口,固实际上在进行跨库操作 从libobjc库
跨越到 dyld
,正好形成了一个闭环
,分析dyld
接口_dyld_objc_notify_register
得知 notifySingle
里面的函数 sNotifyObjCInit
正是 libobjc
库中的loadimages
这里也就得出了结论 , dyld
函数recursiveInitialization
调用 初始化 libobjc
库并向 自己 注册回调函数 得到libobjc库
的函数实现。 在合适的时机 再次调用libobjc
的回调函数实现。 下面我们开始分析_objc_init
到底 做了什么事情,以及向dyld
注册回调函数剩下的函数是什么也就是 _dyld_objc_notify_register
除 loadimages
其他的参数
_objc_init (libobjc)

-
map_images
:dyld 将image镜像文件加载进内存时,会触发该函数 -
load_images
:dyld 初始化image会触发该函数 -
unmap_image
: dyld将image移除时会触发该函数
_dyld_objc_notify_register(dyld)
从 _dyld_objc_notify_register --> void registerObjCNotifiers(

总结

map_images 函数实现
map_images 会调用 map_images_nolock方法 下面为精简代码

map_images 函数调用 (dyld sNotifyObjCMapped
调用时机)
dyld全局搜索 sNotifyObjcMapped ( registerObjCNotifiers --> notifyBatchPartial --> sNotifyObjCMapped)

由此可以看出 map_images
是先于load_images
调用,即先map_images
,再load_images
下一篇 类的加载(上)
网友评论