OBJC alloc 流程分析

373 阅读1分钟

流程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;
}

猜测这就是 [NSObject alloc] 走到了 objc_alloc 方法的原因