美文网首页
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