美文网首页OC底层
isKindOfClass与isMemberOfClass

isKindOfClass与isMemberOfClass

作者: H丶ym | 来源:发表于2020-09-18 15:24 被阅读0次

OC底层原理学习

经典面试题isKindOfClass与isMemberOfClass的理解

//-----使用 iskindOfClass & isMemberOfClass 类方法
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL re3 = [(id)[Person class] isKindOfClass:[Person class]];
BOOL re4 = [(id)[Person class] isMemberOfClass:[Person class]];
        
//------iskindOfClass & isMemberOfClass 实例方法
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL re7 = [(id)[Person alloc] isKindOfClass:[Person class]];
BOOL re8 = [(id)[Person alloc] isMemberOfClass:[Person class]];

isKindOfClass 源码解析

类方法

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

self 指的是,由于类的isa指向元类,所以self->ISA()代表当前类的元类,元类继承于根元类,根元类继承于根类

  1. 获取当前类的元类传入类比较,如果相同返回true,否则继续
  2. 获取当前类的根元类传入类比较,如果相同返回true,否则继续
  3. 获取当前的根类传入类比较,如果相同返回true,否则返回false
  • [(id)[NSObject class] isKindOfClass:[NSObject class]] = true
    第一次循环比较:NSObject 的元类既根元类根类比较,返回 false
    第二次 根元类的父类既根类根类 比较,返回 true

  • [(id)[Person class] isKindOfClass:[Person class]]; = false
    第一次循环比较: Person 的元类Person类比较,返回 false
    第二次 Person 的元类的父类根元类Person类比较,返回 false
    第三次 根元类的父类既根类Person类比较,返回 false
    第四次 根类的父类既nilPerson类比较,返回 false

实例方法

- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}
  1. 获取当前对象的传入类比较,如果相同返回true,否则继续
  2. 获取当前对象的父类传入类比较,如果相同返回true,否则继续
  3. 获取当前对象的根类传入类比较,如果相同返回true,否则继续3.nil 传入类比较,如果相同返回true,否则返回false `
  • [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
    根类根类比较。返回true

  • [(id)[Person alloc] isKindOfClass:[Person class]];
    Person类Person类比较,返回true

isMemberOfClass源码解析

类方法:获取类的元类,与 传入类对比

+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}
  • [(id)[NSObject class] isMemberOfClass:[NSObject class]];
    根元类根类比较,返回false

  • [(id)[Person class] isMemberOfClass:[Person class]];
    元类Person 类比较,返回false

实例方法: 获取对象的类,与 传入类对比

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}
  • [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
    根类根类比较,返回true

  • [(id)[Person alloc] isMemberOfClass:[Person class]];
    Person 类Person 类比较,返回true

总结

根据isa走势图
+号方法 用当前类的->isa,与传入类比较
-号方法 用当前类的class,与传入类比较
isKindOfClass 从下往上找,类走红,对象走蓝
isMemberOfClass 类找元类,对象找类

相关文章

网友评论

    本文标题:isKindOfClass与isMemberOfClass

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