流程RT
[NSObject alloc] 没有走到上述流程的分析
打下断点发现根本就没走到 NSobject.mm 的 + alloc 方法里面,故而没调用 _objc_rootAlloc(Class cls)
汇编发现实际上走到了 objc_alloc(Class cls) 里面
// Base class implementation of +alloc. cls is not nil.
// Calls [cls allocWithZone:nil].
id
_objc_rootAlloc(Class cls)
{
return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
// Calls [cls alloc].
id
objc_alloc(Class cls)
{
return callAlloc(cls, true/*checkNil*/, false/*allocWithZone*/);
}
看这两个方法的注释很有意思,我理解的是上面的方法是继承 NSObject 的类的 +alloc 实现,下面的难道是给 NSObject 专用?
找了半天没发现 objc_alloc(Class cls) 这玩意儿在哪里被调用了,但是显然走到了这个方法以后,也成功实施了 callAlloc。
猜测
又重新复习了预习课 Rumtime源码分析 的内容,objc 方法调用的本质是通过 sel 查找 IMP。
- 第一步为快速查找,通过汇编在缓存里面查找。
- 如果没有查找到,则进入 c语言部分 进行慢速查找。进入 lookUpImpOrForward
- 此处又有一段代码查找缓存,并且有可能找到,原因是第一次加载类的时候会进行重映射
过程大概如下
fixupMessageRef 中有一行代码将 +alloc 的消息映射到了 objc_alloc 上
if (msg->sel == @selector(alloc)) {
msg->imp = (IMP)&objc_alloc;
}