前言
isKindOfClass
和isMemberOfClass
多多少少都用过
isKindOfClass
方法调用者是传入的类的实例对象,或者调用者是传入类的继承者链中的类的实例对象,则返回YES。isMemberOfClass:
returns YES if the receiver is an instance of the specified class.
方法调用者必须是传入的类的实例对象才返回YES。
其实现记录下:
现有TestObject
继承自NSObject
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [(id)[TestObject class] isKindOfClass:[TestObject class]];
BOOL res4 = [(id)[TestObject class] isMemberOfClass:[TestObject class]];
结果为 1 0 0 0
为什么会这样,通过源码分析。
源码
isKindOfClass
和isMemberOfClass
同时支持类和对象方法
+ (BOOL)isMemberOfClass:(Class)cls {
return object_getClass((id)self) == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
//由于对于实例变量,[self class]就是object_getClass(self),所以和类的方法逻辑是一样的,即都是
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass)
//这样就便于记忆
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
执行下面的方法
+ (BOOL)isKindOfClass:(Class)b {
for (Class a = object_getClass((id)self); a; a = a->superclass) {
if (a == b) return YES;
}
return NO;
}
根据runtime
源码,object_getClass
取isa
指针
/***********************************************************************
* object_getClass.
* Locking: None. If you add locking, tell gdb (rdar://7516456).
**********************************************************************/
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
+ (Class)class {
return self;
}
- (Class)class {
return object_getClass(self);
}
由于类的class
就是self
,[NSObject class]
就是NSObject
,object_getClass
取元类,那么就是判断NSObject
元类是否与NSObject
相等。
由于NSObject
元类是根元类,根源类的superclass
指向NSObject
,见下图右上角部分
那么就是相等,所以返回1
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
由于
+ (BOOL)isMemberOfClass:(Class)cls {
return object_getClass((id)self) == cls;
}
NSObject
的元类并不等于NSObject
,返回 0
BOOL res3 = [(id)[TestObject class] isKindOfClass:[TestObject class]];
这里参考1,由于最终返回NSObject
元类的superclass是NSObject
,NSObject
明显不是TestObject
,返回0
4. BOOL res4 = [(id)[TestObject class] isMemberOfClass:[TestObject class]];
同样,元类不能和类相等返回 0
有时候你以为,真的只是你以为,正如rootclass的superclass最终会指向其原类,人在长期的坚持自我之后,会选择向生活妥协,希望你是一个isa的人吧,顽固的自我循环,不再妥协