想要深入立即isKindOfClass和isMemberOfClass的区别,那就离不开下面这个图

image.png
isa 走位链(两条)
teacher的isa走位链:
teacher(子类对象) --> CJLTeacher (子类)--> CJLTeacher(子元类) --> NSObject(根元类) --> NSObject(跟根元类,即自己)person的isa走位图:
person(父类对象) --> CJLPerson (父类)--> CJLPerson(父元类) --> NSObject(根元类) --> NSObject(跟根元类,即自己)
superclass走位链(两条)
类的继承关系链:
CJLTeacher(子类) --> CJLPerson(父类) --> NSObject(根类)--> nil元类的继承关系链:
CJLTeacher(子元类) --> CJLPerson(父元类) --> NSObject(根元类)--> NSObject(根类)--> nil
示例分享
//LGPerson 继承自 NSObject
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL re2 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];
BOOL re3 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL re6 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];
BOOL re7 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];
NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);
输出
2020-09-20 21:15:13.975631+0800 KCObjc[2274:69804]
re1 :1
re2 :0
re3 :0
re4 :0
2020-09-20 21:15:13.976631+0800 KCObjc[2274:69804]
re5 :1
re6 :1
re7 :1
re8 :1
源码分析
+ (BOOL)isKindOfClass:(Class)cls
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
// 获取类的元类 vs 传入类
// 根元类 vs 传入类
// 根类 vs 传入类
if (tcls == cls) return YES;
}
return NO;
}
- 1、 BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
- 传入的
cls为NSObject(根类),self指向NSObject,进入循环tcls= NSObject meta(根元类),执行判断if (tcls == cls),不相等,进入下一个循环tcls= NSObject(根类),执行判断if (tcls == cls),相等,return YES
- 2、 BOOL re2 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];
- 传入的
cls为LGPerson,self指向LGPerson,进入循环tcls= LGPerson meta(元类),执行判断if (tcls == cls),不相等,进入下一个循环tcls= NSObject meta(根元类),执行判断if (tcls == cls),不相等,进入下一个循环tcls= NSObject meta(根类),执行判断if (tcls == cls),不相等,进入下一个循环tcls= nil,结束循环,
+ (BOOL)isMemberOfClass:(Class)cls
+ (BOOL)isMemberOfClass:(Class)cls {
//获取类的元类,与 传入类对比
return self->ISA() == cls;
}
- 3、 BOOL re3 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
- 传入的
cls为NSObject(根类),self指向NSObject,进入循环tcls= NSObject meta(根元类),执行判断if (tcls == cls),不相等
- 4、 BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];
- 传入的
cls为LGPerson,self指向LGPerson,进入循环tcls= NSObject meta(元类),执行判断if (tcls == cls),不相等
- (BOOL)isKindOfClass:(Class)cls
- (BOOL)isKindOfClass:(Class)cls {
//获取对象的类 vs 传入的类
//父类 vs 传入的类
//根类 vs 传入的类
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- 1、 BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
- 传入的
cls为NSObject(根类),self指向NSObject实例对象,进入循环,NSObject实例对象的isa即NSObject(根类)tcls= NSObject(根类),执行判断if (tcls == cls),相等
- 2、 BOOL re6 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];
- 传入的
cls为LGPerson,self指向LGPerson实例对象,进入循环,LGPerson实例对象的isa即LGPersontcls= LGPerson,执行判断if (tcls == cls),相等
- (BOOL)isMemberOfClass:(Class)cls
- (BOOL)isMemberOfClass:(Class)cls {
//获取对象的类,与 传入类对比
return [self class] == cls;
}
- 1、 BOOL re7 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
- 传入的
cls为NSObject(根类),self指向NSObject实例对象,进入循环,NSObject实例对象的类即NSObject(根类)tcls= NSObject(根类),执行判断if (tcls == cls),相等
- 2、 BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];
- 传入的
cls为LGPerson,self指向LGPerson实例对象,进入循环,LGPerson实例对象的类即LGPersontcls= LGPerson,执行判断if (tcls == cls),相等
总结
isKindOfClass
- 类方法:
类和元类的继承链对比
元类(isa) --> 根元类(父类) --> 根类(父类) --> nil(父类)- 实例方法:
对象的类 --> 父类 --> 根类 --> nil与传入类的对比
isMemberOfClass
- 类方法:
类的元类与传入类对比- 实例方法:
对象的父类与传入类对比