isMemberOfClass 和 isKindOfClass

162 阅读1分钟

看一个例子

 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(@"\n 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(@"\n re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);

打印结果为: 1000 1111

解析

话不多说直接上源码

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

![2711707-494ff119aefc462b.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2ff333c88453448786b4c8726d6c59ee~tplv-k3u1fbpfcp-watermark.image?)
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = object_getClass((id)self); 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 re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];// 0

因为这里并没有进行alloc所以我们这里调用的静态方法+ (BOOL)isMemberOfClass:(Class)cls

那么看object_getClass((id)self)得到一个什么玩意儿

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

我们可以看出这里获取的是objisa,也就是元类(mete Class),而我们传进来的是一个 Person类,显然是不相等的所以这里打印结果为false

同样+ (BOOL)isKindOfClass:(Class)cls是通过一个for循环来进行对比判断 Person 继承自NSObject.所以Person的元类的父类为根源类,也就是NSObject的元类 而我们传进来的clsPerson类,所以这里条件不满足返回false 那么

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

为什么打印True呢,因为NSObject的元类的父类也为NSObject,满足条件所以打印True

附上经典isa走位图 2711707-494ff119aefc462b.png