面试题: isKindOfClass & isMemberOfClass

先复习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 & isMemberOfClass)