前言
这个归根结底还是在考察我们对isa走向图和类的继承的理解,也就是苹果官方这幅图:
接下来的函数调用流程请参考这张图。
1 isKindOfClass方法
1.1 objc_opt_isKindOfClass C函数
查看源码可发现,无论是谁调用isKindOfClass
方法都会进入这个C函数。(这个C函数位于NSObjective.mm
)
// Calls [obj isKindOfClass]
// 当obj调用isKindOfClass时,objc_opt_isKindOfClass会被触发
// obj是一个id类型,id是一个objc_object结构体指针,意味着,传进来的可以是时类,也可以是类的实例对象
// otherClass就是isKindOfClass的参数,我们当初传进去的cls
BOOL objc_opt_isKindOfClass(id obj, Class otherClass)
{
#if __OBJC2__
if (slowpath(!obj)) return NO;
Class cls = obj->getIsa(); // 此处的cls仅是obj的第一个isa
if (fastpath(!cls->hasCustomCore())) {
// otherClass 从obj的ISA开始,依次和ISA的父类比较,直到找到或者父类为nil结束
// 当父类为nil意味着最后一个和otherClass比较的是NSObject根类。
for (Class tcls = cls; tcls; tcls = tcls->superclass) {
if (tcls == otherClass) return YES;
}