OC底层

isKindOfClass与isMemberOfClass

2020-09-18  本文已影响0人  H丶ym

OC底层原理学习

经典面试题isKindOfClass与isMemberOfClass的理解

//-----使用 iskindOfClass & isMemberOfClass 类方法
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL re3 = [(id)[Person class] isKindOfClass:[Person class]];
BOOL re4 = [(id)[Person class] isMemberOfClass:[Person class]];
        
//------iskindOfClass & isMemberOfClass 实例方法
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL re7 = [(id)[Person alloc] isKindOfClass:[Person class]];
BOOL re8 = [(id)[Person alloc] isMemberOfClass:[Person class]];

isKindOfClass 源码解析

类方法

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

self 指的是,由于类的isa指向元类,所以self->ISA()代表当前类的元类,元类继承于根元类,根元类继承于根类

  1. 获取当前类的元类传入类比较,如果相同返回true,否则继续
  2. 获取当前类的根元类传入类比较,如果相同返回true,否则继续
  3. 获取当前的根类传入类比较,如果相同返回true,否则返回false

实例方法

- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}
  1. 获取当前对象的传入类比较,如果相同返回true,否则继续
  2. 获取当前对象的父类传入类比较,如果相同返回true,否则继续
  3. 获取当前对象的根类传入类比较,如果相同返回true,否则继续3.nil 传入类比较,如果相同返回true,否则返回false `

isMemberOfClass源码解析

类方法:获取类的元类,与 传入类对比

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

实例方法: 获取对象的类,与 传入类对比

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

总结

根据isa走势图
+号方法 用当前类的->isa,与传入类比较
-号方法 用当前类的class,与传入类比较
isKindOfClass 从下往上找,类走红,对象走蓝
isMemberOfClass 类找元类,对象找类

上一篇 下一篇

猜你喜欢

热点阅读