想要深入立即isKindOfClass
和isMemberOfClass
的区别,那就离不开下面这个图
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
- 类方法:
类的元类
与传入类
对比- 实例方法:
对象的父类
与传入类
对比
网友评论