接上一篇文章 iOS-App的加载过程-01, 继续分析 App 的加载过程, 那么我们接着上篇文章的七个步骤.
以上七个步骤中, 前6个已经基本明了, 还没有看到执行到 main()
函数, 接下来就剩下第七步中 initializeMainExecutable();
和 notifyMonitoringDyldMain();
- 7.1 我们先跳进
initializeMainExecutable();
函数, 发现里边主要调用runInitializers
这个函数分别运行所有动态库和主程序.
initializeMainExecutable 函数
如果跳不进去, xcode12是跳不进去的, 需要全局搜索
runInitializers(const
.
- 7.2 说明还没有到最后, 那我们继续跳进
runInitializers
这个函数内部看看具体实现. 从这个函数中我们还是没有找到最终结果, 但是发现一个重要函数processInitializers(context, thisThread, timingInfo, up);
已经标记出来了.
- 7.3 继续跳进
processInitializers
函数, 我的天呀, 还没有到最终, 淡定, 接着往下找, 重点recursiveInitialization
已经标记出来了.
-7.4 继续跳进 recursiveInitialization
函数, 发现有一个 if {}
代码块代码比较多, 我们先折叠起来, 整体看下, 又发现其他没什么重点, 那么重点肯定在 if
代码块里了.
ImageLoader::recursiveInitialization注意: 是 ImageLoader::recursiveInitialization
- 7.4.1 接下来看
if
里边的代码, 经过一番苦苦查找, 终于找到了这个函数的重点notifySingle
函数. 还没有到最后, 能有什么办法呢, 接着往下找吧.
- 7.5 点击进入发现是个函数指针声明, 只能全局搜索
notifySingle(
, 找到唯一一个函数实现. 又经过一番查找, 发现重点是第941行(*sNotifyObjCInit)(image->getRealPath(), image->machHeader());
- 7.6 点击跳进去并没有找到
sNotifyObjCInit
的实现, 然后全局搜索sNotifyObjCInit
, 最后在registerObjCNotifiers
函数中找到了一个赋值语句. 原来这是外界传入的函数. 那我们看看registerObjCNotifiers
函数是在哪里调用的,init
这个参数是从哪里传过来的.
- 7.7 全局搜索
registerObjCNotifiers
, 找到调用地方, 发现实际上sNotifyObjCInit
是_dyld_objc_notify_register
函数的第二个参数. 那我们继续找_dyld_objc_notify_register
这个函数吧,
7.8 全局搜索 _dyld_objc_notify_register(
, 发现没有找到调用他的地方, 线索到这里就断了, 走不通了, 那么我们就得回去, 重新回到 7.4.1
的 if
代码块里, 看看是不是漏掉了什么, 仔细查找, 你细品. 两个notifySingle
中间有一行代码, 注释是 initialize this image
, 初始化, 看样子很重要, 那还犹豫什么, 赶紧跳进去看看吧.
未完待续/........
查找流程
initializeMainExecutable
runInitializers
processInitializers
recursiveInitialization
网友评论