下面两段代码,输出结果是否符合预期呢?
BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];//<1>
BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];//<2>
BOOL res3 = [[LTClass class] isKindOfClass:[LTClass class]];//<3>
BOOL res4 = [[LTClass class] isMemberOfClass:[LTClass class]];//<4>
NSLog(@"res1=%hhd,res2=%hhd,res3=%hhd,res4=%hhd",res1,res2,res3,res4);
BOOL res5 = [[NSObject alloc] isKindOfClass:[NSObject class]];//<5>
BOOL res6 = [[NSObject alloc] isMemberOfClass:[NSObject class]];//<6>
BOOL res7 = [[LTClass alloc] isKindOfClass:[LTClass class]];//<7>
BOOL res8 = [[LTClass alloc] isMemberOfClass:[LTClass class]];//<8>
NSLog(@"res5=%hhd,res6=%hhd,res7=%hhd,res8=%hhd",res5,res6,res7,res8);
对象、类、元类的关系图(虚线为iSA,实线为继承关系) 图1上图中,Root class(class)其实就是NSObject
objc源码来揭开其真实的底层逻辑:
isKindOfClass类方法通过源码(截图代码来自Apple的objc源码),在类方法isKindOfClass中有一个循环,先判断class是否等于meta class,不等就判断是否等于meta class的superclass,不等就继续取superclass,如此循环下去
对应到代码<1>中:
[NSObject class],NSObject调用类方法class返回self(即:NSObject);
将NSObject与NSObject->iSA(即:NSObject meta class 元类)进行比较,NSObject不等于NSObject meta class;
继续取NSObject meta class的superclass,由上面的关系图可知,NSObject meta class的superclass为NSObject;那么此时NSOjbect==NSObject,所以返回YES
对应到代码<3>中:
将LTClass与LTClass->iSA(即:LTClass meta class)进行比较,二者不相等;
继续取LTClass meta class的superclass(即:NSObject meta class)进行比较,LTClass与NSObject meta class不相等
继续取NSObject meta class的superclass(即:NSObject),LTClass与NSObject不相等
继续取NSObject的superclass(即:nil),LTClass与nil不相等;至此循环结束,返回NO
class类方法 isMemberOfClass类方法isMemberOfClass的类方法可知,是判断当前类的meta class 与 class进行比较(即:将自己与自己的iSA进行比较)
对应到代码<2>中:将NSObject 的meta class与NSObject比较,不相等,所以返回NO
对应到代码<4>中:将NTClass 的meta class与NTClass比较,不相等,所以返回NO
isKindOfClass实例方法 class实例方法 object_getClass方法通过源码可知:实例方法isKindOfClass中同样是有一个循环,先调用实例的class方法,class方法调用object_getClass(self)方法,object_getClass方法返回obj->getIsa()即:返回实例对象的iSA对象也就是类
对应到代码<5>中:[NSObject alloc]返回NSObject的实例,进入到isKindOfClass方法中,
首先通过NSObject的实例的class方法获取到类(即:NSObject),[NSObject class]直接返回NSObject;NSObject与NSObject相等,结束循环,返回YES
对应到代码<7>中:[LTClass alloc]返回LTClass的实例,进入到isKindOfClass方法中,
首先通过NTClass的实例的class方法获取到类(即:NTClass),[NTClass class]直接返回NTClass,NTClass与NTClass相等,结束循环,返回YES
isMemberOfClass实例方法通过源码可知:实例方法isMemberOfClass是通过实例调用class方法,然后调用object_getClass方法返回类;然后将返回的类与目标类进行比较;
对应到代码<6>中:[NSObject alloc]返回NSObject的实例,进入到isMemberOfClass方法中,
通过NSObject的实例的class方法获取到类(即:NSObject),[NSObject class]直接返回NSObject, NSObject与NSObject相等,返回YES
对应到代码<8>中:[LTClass alloc]返回NTClass的实例,进入到isMemberOfClass方法中,
通过NTClass的实例的class方法获取到类(即:LTClass),[LTClass class]直接返回LTClass,LTClass与LTClass相等,返回YES
综上分析:
类方法isKindOfClass,先获取类对象的iSA即元类,元类继承链与指定类对比
实例方法isKindOfClass,先获取实例对象的iSA即类,类继承链与指定类对比
类方法isMemberOfClass,先获取类对象的iSA即元类,元类与指定类对比
实例方法isMemberOfClass,先获取实例对象的iSA即类,类与指定类对比
代码<1>到代码<8>输出的结果为:
1000
1111
网友评论