美文网首页
isMemberOfClass 和 isKindOfClass

isMemberOfClass 和 isKindOfClass

作者: 平常心_kale | 来源:发表于2020-12-22 15:20 被阅读0次

1. 思考如下代码的输出

int main(int argc, const char * argv[]) {
    BOOL b1 = [[YYPerson class] isKindOfClass:[YYPerson class]];
    BOOL b2 = [[YYPerson class] isMemberOfClass:[YYPerson class]];
    BOOL b3 = [[NSObject class] isKindOfClass:[NSObject class]];
    BOOL b4 = [[NSObject class] isMemberOfClass:[NSObject class]];
    NSLog(@"%d, %d, %d, %d", b1, b2, b3, b4);
    return 0;
}

以上代码输出:0, 0, 1, 0

2. 同样的原理,我们回答问题之前,先要知道 isKindOfClass 和 isMemberOfClass 底层到底调用了什么方法?

//类调用
+ (BOOL)isMemberOfClass:(Class)cls {
    return object_getClass((id)self) == cls;
}
或者
+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}

- (BOOL)isMemberOfClass:(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->ISA(); 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;
}

1.类方法和实例方法的区别:实例方法[self class]拿的是类对象 ,类方法objc_getClass(self)拿的是元类对象。
2.isMemberOfClass:只会对比当前对象是否和目标对象相等; isKindOfClass:会查找当前对象以及它的父类对象中有没有和目标对象相等的;

练习一
int main(int argc, const char * argv[]) {
    YYPerson *person = [[YYPerson alloc] init];
    NSLog(@"%d", [person isMemberOfClass:[YYPerson class]]);
    NSLog(@"%d", [person isMemberOfClass:[NSObject class]]);
    NSLog(@"%d", [person isKindOfClass:[YYPerson class]]);
    NSLog(@"%d", [person isKindOfClass:[NSObject class]]);
    return 0;
}

===
Demo[16964:980177] 1 // 1 等价于: [person class] == [YYPerson class]
Demo[16964:980177] 0 // 0 等价于: [person class] == [NSObject class]
Demo[16964:980177] 1 // 1 等价于: YYPerson类对象以及父类对象  == YYPerson类对象
Demo[16964:980177] 1 // 1 等价于: YYPerson类对象以及父类对象  == NSObject类对象
练习二
int main(int argc, const char * argv[]) {
    NSLog(@"%d", [YYPerson isMemberOfClass:object_getClass([YYPerson class])]);
    NSLog(@"%d", [YYPerson isKindOfClass:object_getClass([NSObject class])]);
    return 0;
}

====
Demo[17167:991810] 1 // 1 等价于: YYPerson元类对象  == YYPerson元类对象
Demo[17167:991810] 1 // 1 等价于: YYPerson元类对象以及父元类对象  == NSObject元类对象
练习三
int main(int argc, const char * argv[]) {
    NSLog(@"%d", [[YYPerson class] isKindOfClass:[YYPerson class]]);
    NSLog(@"%d", [[YYPerson class] isMemberOfClass:[YYPerson class]]);
    NSLog(@"%d", [[NSObject class] isKindOfClass:[NSObject class]]);
    NSLog(@"%d", [[NSObject class] isMemberOfClass:[NSObject class]]);
    return 0;
}
===
Demo[16797:971234] 0 // 0 等价于: YYPerson的元类以及父元类 == YYPerson的类对象
Demo[16797:971234] 0 // 0 等价于: YYPerson的元类 == YYPerson的类对象
Demo[16797:971234] 1 // 1 等价于: NSObject的元类以及父元类 == NSObject的类对象 (根元类superclass 指向 NSObject的类对象)
Demo[16797:971234] 0 // 0 等价于: NSObject的元类 == NSObject的类对象

相关文章

网友评论

      本文标题:isMemberOfClass 和 isKindOfClass

      本文链接:https://www.haomeiwen.com/subject/fvssnktx.html