美文网首页
iOS之isKindOfClas、isMemberOfClass

iOS之isKindOfClas、isMemberOfClass

作者: 枫叶无处漂泊 | 来源:发表于2020-07-12 23:59 被阅读0次

    首先我们先来看一段代码:

    @interface Person : NSObject
    @end
    @implementation Person
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
    
            NSLog(@"%@", [NSObject class]);
            NSLog(@"%@", [Person class]);
    
            BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
            BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
            BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
            BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
            NSLog(@"%d--%d--%d--%d", res1, res2, res3, res4);
        }
        return 0;
    }
    

    输入结果:

     NSObject
     Person
     1-0-0-0
    

    可能执行结果出乎大多数人的意料,

    如果不是很清楚对象、类对象、元类关系的,可以先看一下下图:


    对象、类对象、元类关系.png
    • 对象的isa指针指向类对象
    • 类对象的指针指向元类
    //类对象返回自身
    + (Class)class {
        return self;
    }
    

    [NSObject class]、[Person class]返回还是当前类对象

    下面可以看看两个isMemberOfClass、isKindOfClass内部实现,

    //isMemberOfClass实现
    - (BOOL)isMemberOfClass:(Class)cls {
        return [self class] == cls;
    }
    
    

    isMemberOfClass比较两个isa指向的类对象是否一样。

    能判断对象是否是当前类的实例对象.

    //isKindOfClass实现
    - (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    

    前者对象的(class)类对象是否与后者类对象相同,如果相同返回YES
    不相等的话就,就继续对象的类对象的superclass看是否相等,一直找到根类

    一、 [(id)[NSObject class] isKindOfClass:[NSObject class]];

    其实通过isKindOfClass内部实现源码,可以理解为:

    • 前者[[NSObject class] class](NSObject的Meta Class)与后者[NSObject class](NSObject的class)是否相等
    • 相等返回true
    • 不相等的话,就遍历NSObject的元类的superclass,看是否相等.
    • 如上图NSObject的元类的superclass指向NSObject的类对象,所以返回的true。

    二、[(id)[NSObject class] isMemberOfClass:[NSObject class]]

    • isMemberOfClass只能判断对象是否是当前类的实例对象,NSObject的元类肯定不是NSObject类对象的实例。所以返回false。

    三、[(id)[Person class] isKindOfClass:[Sark class]];

    执行流程大概是这样:

    • [[Person class]class] 执行完之后调用 isKindOfClass,
      1. 第一次 for 循环,Person 的 Meta Class 与 [Person class] 不等,
      2. 第二次 for 循环,Person Meta Class 的 super class 指向的是 NSObject Meta Class, 和 Person Class 不相等。
      3. 第三次 for 循环,NSObject Meta Class 的 super class 指向的是 NSObject Class,和 Person Class 不相等。
      4. 第四次循环,NSObject Class 的super class 指向 nil, 和 Person Class 不相等。第四次循环之后,退出循环,所以第三行的 res3 输出为 NO。

    四、[(id)[Sark class] isMemberOfClass:[Sark class]]

    isa 指向 Person 的 Meta Class,和 Person Class 也不等。

    相关文章

      网友评论

          本文标题:iOS之isKindOfClas、isMemberOfClass

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