isKindOfClass、isMemberOfClass

这也是一个老话题了,面试中常见的问题,再来简单回顾一下。
首先再补充一下知识点(可以直接看最后的FAQ部分):http://www.jianshu.com/p/7402c75f84a9

现在来看一下这几个方法的源码

+ (BOOL)isMemberOfClass:(Class)cls {
//object_getClass((id)self)拿到的是当前类的元类
//即判断cls是否是当前类的元类
    return object_getClass((id)self) == cls;
}

- (BOOL)isMemberOfClass:(Class)cls {
//[self class]返回当前类对象
//即判断cls是否是对象实例的类
    return [self class] == cls;
}

+ (BOOL)isKindOfClass:(Class)cls {
//从当前类的元类开始向上判断
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

- (BOOL)isKindOfClass:(Class)cls {
//从当前类对象开始向上判断
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

再看几个示例

BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [[UIViewController class] isKindOfClass:[UIViewController class]];
BOOL res4 = [[UIViewController class] isMemberOfClass:[UIViewController class]];
BOOL res5 = [[UIViewController class] isKindOfClass:[NSObject class]];
NSLog(@"%d %d %d %d %d", res1, res2, res3, res4, res5);
//结果为1 0 0 0 1

让我们简单分析一下:
先看res2和res4,res2和res4都为NO的原因是相同的,就拿res2来说,这句话可以翻译为:BOOL res2 = object_getClass([NSObject class]) == [NSObject class], object_getClass([NSObject class]得到的是NSObject的元类,显然和NSObject是不同的

再看一下res3,这句话可以翻译为:

    for (Class tcls = object_getClass([UIViewController class]); tcls; tcls = tcls->superclass) {
        if (tcls == [UIViewController class]) return YES;
    }
    return NO;

从UIViewController的元类开始向上找,分别能找到UIResponder的元类,NSObject的元类,NSObject类对象,nil,而不会找到UIViewController这个类对象,所以为NO

此时,再看res1,NSObject的元类的superclass是NSObject本身,所以for循环到第二次是便会出现相等的情况,结果为YES

最后看res5,结合刚才的res1和res3,就比较明确了。

关于这些类实例,类对象和元类之间的关系,只要记住下面这张图就可以了,这张图在上面提到的知识点中也有说到

isKindOfClass、isMemberOfClass_第1张图片
类-实例-元类关系图.PNG

上面的示例使用的都是类方法,主要是因为类方法比较容易出错,对于实例方法,可以完全按照字面意思理解即可

    BOOL res6 = [self isKindOfClass:[ViewController class]];
    BOOL res7 = [self isKindOfClass:[UIViewController class]];
    BOOL res8 = [self isKindOfClass:[NSObject class]];
    BOOL res9 = [self isMemberOfClass:[ViewController class]];
    BOOL res10 = [self isMemberOfClass:[UIViewController class]];
    BOOL res11 = [self isMemberOfClass:[NSObject class]];
    NSLog(@"%d %d %d %d %d %d", res6, res7, res8, res9, res10, res11);
 //结果为1 1 1 1 0 0

你可能感兴趣的:(isKindOfClass、isMemberOfClass)