zoukankan      html  css  js  c++  java
  • isKindOfClass和isMemberOfClass原理

    面试题,下面代码的结果是什么?

    BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //
        BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //
        BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];       //
        BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];     //
        
        NSLog(@"%ld %ld %ld %ld",re1,re2,re3,re4);
        
        BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //
        BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //
        BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];       //
        BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];     //
        
        NSLog(@"%ld %ld %ld %ld",re5,re6,re7,re8);

    打印:

    2021-05-12 15:59:07.807569+0800 Test[35410:1126191] 1 0 0 0
    2021-05-12 15:59:07.807711+0800 Test[35410:1126191] 1 1 1 1

    这里需要明白isKindOfClass和isMemberOfClass的不同点,先看看runtime中的源码:

    + (BOOL)isMemberOfClass:(Class)cls {
        return self->ISA() == cls;
    }
    
    - (BOOL)isMemberOfClass:(Class)cls {
        return [self class] == cls;
    }
    
    + (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;
    }

    实例方法

    - (BOOL)isMemberOfClass:(Class)cls {} 用来判断某个对象是否属于某个类

    - (BOOL)isKindOfClass:(Class)cls {} 用来判断某个对象是否属于某个类,或者是属于某个派生类。

    所以,re5 re6 re7 re8 都打印1

    类方法打印结果需要结合下图理解

    NSObject 和 LGPerson 的 isMemberOfClass

    res2 是 NSObject 的 isa 指针 NSObject 的元类 与 NSObject 做对比。返回 No ,不相等

    res4 是 LGPerson 的 isa 指针 LGPerson 的元类 与 LGPerson 做对比。返回 No ,不相等

    NSObject 和 LGPerson 的 isKindOfClass

    接下来分析 res1 和 res3 的答案。

    分析 res1 ,在 isKindOfClass 中有个循环,先判断是否等于 NSObject 的元类,不等就继续循环,判断是否等于 NSObject 元类 的父类 NSObject。返回 YES ,相等

    分析 res3 ,在 isKindOfClass 中有个循环,先判断是否等于 LGPerson 的元类,不等就继续循环,判断是否等于 LGPerson 元类 的父类 NSObject 元类。不等就继续循环,判断是否等于 NSObject 元类 的父类 NSObject。不等就继续循环,判断是否等于 NSObject 的父类。NSObject 的父类为 nil ,结束循环。返回 NO ,不相等

    总结:

    类方法 isKindOfClass 会先判断是否等于对象的元类,不等就继续循环,判断是否等于对象的元类的父类。若相等,结束返回YES,若不相等,继续循环迭代。若最终判断至 NSObject 的父类 为 nil ,结束返回NO。先判断 isa ,再判断 superclass 。

    类方法 isMemberOfClass 不循环判断 isa 。只判断一次,对象的元类与对象做比较。结束返回NO。

    在北京的灯中,有一盏是我家的。这个梦何时可以实现?哪怕微微亮。北京就像魔鬼训练营,有能力的留,没能力的走……
  • 相关阅读:
    Docker安装模拟MySQL集群
    Java中类似PHP的var_dump()
    同样的sql语句在数据库中能查出结果,但是在java springboot项目中,查不出来
    import org.junit.Test 导入失败 @Test JUnit4单元测试找不到
    解决用eclipse spring start project 自动创建项目时pom文件错误
    Laravel 队列的简单使用例子
    跨库触发器
    MySQL 主从复制 详细实例讲解 与 常见错误解决方法
    2014年末总结:对大数据处理的一点思考
    Range
  • 原文地址:https://www.cnblogs.com/huangzs/p/14760850.html
Copyright © 2011-2022 走看看