iOS-isKindOfClass VS isMemberOfClass

516 阅读1分钟

isKindOfClass VS isMemberOfClass 各自有对应的实例方法类方法,源码如下:

+ (BOOL)isMemberOfClass:(Class)cls {
    // 元类 VS 类
    return object_getClass((id)self) == cls;
}

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

+ (BOOL)isKindOfClass:(Class)cls {
    //    for (int i= 0; i<10; i++) {
    //    }
    // NSObject元类 vs NSObject类
    // 元类的父类 - NSObject vs NSObject
    
    // LGPerson元类 vs LGPerson
    // NSObject vs LGPerson
    //**object_getClass** 返回对应的**元类**
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

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

验证:

void test3() {
    // 此处都调用对应的 + 类方法
    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的方法都进行了for循环查找父类的历程,-实例方法查找当前类的父类,+类方法查找元类的父类进行比较。PS:NSObject元类的父类是NSObject,NSObject的父类是nil

isMemberOfClass实例方法是当前类与cls的比较,类方法是元类与cls的比较。