美文网首页iOS面试题题库iOS常识
面试题: isKindOfClass & isMemberOfC

面试题: isKindOfClass & isMemberOfC

作者: KB_MORE | 来源:发表于2020-09-14 09:54 被阅读0次

    先复习isa走位和继承流程图


    isa流程图.png
            BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //1
            BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //0
            BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];       //0
            BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];     //0
            NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
    
            BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //1
            BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //1
            BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];       //1
            BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];     //1
            NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);
    

    在前四题中是调用的类方法

    • +isKindOfClass
    • +isMemberOfClass
      先看下这两种类方法的底层实现:
      isKindOfClass
    + (BOOL)isKindOfClass:(Class)cls {
       // 获取类的元类 vs 传入类
        // 根元类 vs 传入类
        // 根类 vs 传入类
        for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    

    第一题: BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]]; //1

    解析

    类(NSObject)元类(元类NSObject) 是否等于类(NSObject) ?
    显然不等, 然后 tcls赋值为tcls的父类(元类NSObject的父类为NSObject), isKindOfClass传入的参数 cls (NSObject) == 此时的tcls(NSObject)
    所以返回YES

    图片.png

    第三题 BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]]; //0

    解析

    1.类(LGPerson)元类(元类LGPerson) 是否等于类(LGPerson) ? 不等
    2.元类(元类LGPerson)父类(元类NSObject)是否登录类(LGPerson) ? 不等
    3.元类NSObject)的父类(根源类(NSObject))是否等于类(LGPerson) ? 不等
    4.根源类(NSObject)的父类(NSObject)是否登录类(LGPerson) ? 不等
    5.NSObject父类(nil)是否登录类(LGPerson) ? 不等
    返回nil

    isMemberOfClass

    + (BOOL)isMemberOfClass:(Class)cls {
       //元类 vs 类
        return self->ISA() == cls;
    }
    

    第二题 : BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]]; //0

    解析

    类的元类 ==?
    元类(元类NSObject) ==类(NSObject) ?
    显然不等 返回NO

    图片.png

    第四题 : BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]]; //0

    解析

    1.类LGPerson元类(元类LGPerson) 是否等于类(LGPerson) ? 不等

    在后四题中是调用的类方法

    • -isKindOfClass
    • -isMemberOfClass
      先看下这两种类方法的底层实现:

    -isKindOfClass

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

    第五题 BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]]; //1

    解析

    1.类(NSObject)class (NSObject) 是否等于 类(NSObject) ? 相等
    返回YES

    第七题 BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]]; //1

    解析

    1.类(LGPerson)class (LGPerson) 是否等于 类(LGPerson) ? 相等
    返回YES

    -isMemberOfClass

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

    第六题 BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]]; //1

    解析

    1.类(NSObject)class (NSObject) 是否等于 类(NSObject) ? 相等
    返回YES

    第八题 BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]]; //1

    解析

    1.类(LGPerson)class (LGPerson) 是否等于 类(LGPerson) ? 相等
    返回YES

    源码分析总结

    isKindOfClass

    类方法元类 --> 根元类 --> 根类 -->nil传入类的对比
    实例方法对象的类 --> 父类 --> 根类 --> nil传入类的对比

    isMemberOfClass

    类方法类的元类传入类 对比
    实例方法对象的父类传入类 对比

    相关文章

      网友评论

        本文标题:面试题: isKindOfClass & isMemberOfC

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