isMemberOfClass 和 isKindOfClass 区别
先从面试题的打印语句开始:
***********************?MJPerson.h ?**************************
#import <Foundation/Foundation.h>
@interface MJPerson : NSObject
@end
***********************?MJPerson.m ?**************************
#import "MJPerson.h"
@implementation MJPerson
@end
四句输出语句,仔细想想会打印输出什么:
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"%d", [NSObject isKindOfClass:[NSObject class]]); // 1
NSLog(@"%d", [NSObject isMemberOfClass:[NSObject class]]); // 0
NSLog(@"%d", [MJPerson isKindOfClass:[MJPerson class]]); // 0
NSLog(@"%d", [MJPerson isMemberOfClass:[MJPerson class]]); // 0
}
}
RUN>
*********************** ?运行结果? ************************** 2021-05-08 15:33:35.732674+0800 Interview01-class[3834:142154] 1 2021-05-08 15:33:35.733220+0800 Interview01-class[3834:142154] 0 2021-05-08 15:33:35.733273+0800 Interview01-class[3834:142154] 0 2021-05-08 15:33:35.733296+0800 Interview01-class[3834:142154] 0
找到源码
+ (BOOL)isMemberOfClass:(Class)cls {
// 获取接收者的元类对象 , 直接和 传进来的 cls 比较,也就是说传进来的 cls 也应该是 元类对象,否则就为 false
return object_getClass((id)self) == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
// 获取消息接收者的类对象 和 传入的 cls 判断是否相等
return [self class] == cls;
}
+ (BOOL)isKindOfClass:(Class)cls {
// 第一步: 获取传入的消息接收者的元类对象
// 第二步: 判断和传入的 cls 是否相等,也就是说传入的也必须是 元类对象, 否则为 false
// 第三步: 如果不相等,继续找这个 元类对象的 superclass 继续比较,直到 superclass 为 nil.
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
// 第一步: 取出消息接收者的类对象,和传入的 cls 判断是否相等
// 第二步: 如果不相等,继续找这个类对象的 superclass 继续比较,直到 superclass 为nil 为止.
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
根据源码分析,+
开头的方法,==传入的必须是元类对象==,所以我们后面三条输出语句都是false
.
[NSObject isKindOfClass:[NSObject class]]
也是使用的+类方法,比较的元类对象,为什么输出的true
在OC对象的本质-isa指针 superclass指针详解
因为基类元类对象的 superclass 指向类对象
所以最后回到了NSObject
类对象,事实上,所有继承自NSObject
类的子类调用[isKindOfClass:[NSObject class]]
都是成立的.
特别备注
本系列文章总结自MJ老师在腾讯课堂iOS底层原理班(下)/OC对象/关联对象/多线程/内存管理/性能优化,相关图片素材均取自课程中的课件。如有侵权,请联系我删除,谢谢!