- (BOOL)isKindOfClass:(Class)aClass;
Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class.
返回一个布尔值,该值指示接收方是给定类的实例还是从该类继承的任何类的实例。
- (BOOL)isMemberOfClass:(Class)aClass;
Returns a Boolean value that indicates whether the receiver is an instance of a given class.
返回一个布尔值,该值指示接收方是否为给定类的实例。
查看objc源码:
+ (Class)class {
return self;
}
- (Class)class {
return object_getClass(self);
}
+ (Class)superclass {
return self->getSuperclass();
}
- (Class)superclass {
return [self class]->getSuperclass();
}
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
+ (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;
}
可以看到isMemberOfClass:和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;
}
isa指针走向.png
以NSString为例:
isa
面试题,如下打印什么?为什么?
BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [[Person class] isKindOfClass:[Person class]];
BOOL res3 = [[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res4 = [[Person class] isMemberOfClass:[Person class]];
NSLog(@"res1: %d=res2: %d=res3: %d=res4: %d", res1, res2, res3, res4);
分析这样的,个人感觉需要对上面的isa指针走向图做到心中有图,以及对isKindOfClass:和isMemberOfClass:方法的底层实现做到理解。
BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
很显然,这里第一个调用者是[NSObject class],即是一个类对象在调用isKindOfClass:而不是某个类的实例对象。
结合isKindOfClass的底层实现:
[NSObject class],即NSObject类对象,而调用isKindOfClass:
则:
(Class tcls = self->ISA()) NSObject类对象的isa指针指向的是NSObject根元类, NSObject根元类 != NSObject类,循环继续;
- tcls = tcls->getSuperclass(),NSObject根元类的父类是NSObject类,此时 tcls == cls,return YES;
BOOL res2 = [[Person class] isKindOfClass:[Person class]];
- [Person class]为Person类对象,Person类对象的isa指向Person的元类对象, Person元类 != Person类,循环继续
- Person元类的superclass是根元类,根元类 != Person类,循环继续;
- 根元类的superclass是NSObject类,NSObject类 != Person类,循环继续;
- NSObject类的superclass是nil,nil != Person类,循环结束
- return NO;
BOOL res3 = [[NSObject class] isMemberOfClass:[NSObject class]];
[NSObject class] NSObject类的isa指向的是根元类,根元类 != NSObject类, return NO
BOOL res4 = [[Person class] isMemberOfClass:[Person class]];
[Person class] Person类的isa指向的是Person的元类,Person元类 != Person类,return NO
理解isKindOfClass和isMemberOfClass的区别
iOS底层原理 06 : isa走位&类继承的经典面试题
深入理解iOS开发中的isa指针











网友评论