isKindOfClass
以前了解的isKindOfClass
源码实现如下:
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass()) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {
if (tcls == cls) return YES;
}
return NO;
}
在工程中测试isKindOfClass的功能按照这边的源码来解析也是对的,但后面再objc源码中打断点的时候,突然发现了这边的断点竟然没有进,通过反汇编查看了调用isKindOfClass真正进的方法是objc_opt_isKindOfClass,骗了我好些年。。
分析objc_opt_isKindOfClass源码
源码如下,isKindOfClass无论调用的是实例方法还是类方法,都会调用以下代码
BOOL objc_opt_isKindOfClass(id obj, Class otherClass) {
#if __OBJC2__
if (slowpath(!obj)) return NO;
Class cls = obj->getIsa();
if (fastpath(!cls->hasCustomCore())) {
for (Class tcls = cls; tcls; tcls = tcls->getSuperclass()) {
if (tcls == otherClass) return YES;
}
return NO;
}
#endif
return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
}
源码可以看出,在非__OBJC2__环境下还是会走之前的isKindOfClass的类方法和实例方法
举几个个人认为比较经典的例子
Person *p = [[Person alloc] init];
NSObject *objc = [[NSObject alloc] init];
BOOL res1 = [p isKindOfClass:[Person class]]; //YES
BOOL res2 = [[Person class] isKindOfClass:[Person class]]; //NO
BOOL res3 = [objc isKindOfClass:[NSObject class]]; //YES
BOOL res4 = [[NSObject class] isKindOfClass:[NSObject class]];//YES
根据上面的图、源码、res1、res4来分析一下
BOOL res1 = [p isKindOfClass:[Person class]];
第一次进循环:
tcls = cls = obj->getIsa();,此时tcls为Person类对象- otherClass的传参是
[Person class],也是Person类对象
两者比较结果为YES,直接返回YES
BOOL res4 = [[NSObject class] isKindOfClass:[NSObject class]];
第一次循环:
tcls = cls = obj->getIsa();,传入的obj为NSObject类对象,则tcls为NSObject元类对象- otherClass的传参是
[NSObject class],是NSObject类对象 - tcls != otherClass,进入下次循环
第二次循环:
tcls = tcls->getSuperclass(),NSObject元类对象的isa指向为NSObject类对象,此时tcls为NSObject类对象- otherClass也为NSObject类对象
两者比较结果为YES,直接返回YES
isMemberOfClass
先看源码
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
因为比较简单,就不举例了
类方法是前一个参数的isa指针指向的内容与后一个参数进行比较
示例方法是前一个参数的类对象与后一个参数进行比较