isKindOfClass 和 isMemberOfClass分析

isKindOfClass分析

isKindOfClass分类方法和对象方法两种。

  • 类方法: 将类和元类进行比较
// 类方法
+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass()) {
        if (tcls == cls) return YES;
    }
    return NO;
}
复制代码
  • 对象方法: 当前类和类进行比较
// 对象方法
- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {
        if (tcls == cls) return YES;
    }
    return NO;
}
复制代码
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //
BOOL re2 = [(id)[JCPerson class] isKindOfClass:[JCPerson class]];       //
NSLog(@" re1 :%hhd\n re2 :%hhd\n",re1,re2,);

BOOL re3 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //
BOOL re4 = [(id)[JCPerson alloc] isKindOfClass:[JCPerson class]];       //
NSLog(@" re3 :%hhd\n re4 :%hhd\n",re3,re4);

复制代码

输出的结果为1,0,1,1

[NSObject class] 类和NSObject的元类都是NSObject re1为1;

[JCPerson class] 为JCPerson, [JCPerson class]元类是NSObject re2为0;

[NSObject alloc]对象的类为NSObject[NSObject class] 类为NSObject re3为1;

[JCPerson alloc] 对象类JCPerson[JCPerson class]类为JCPersonre4为1;

坑点 当你编译源码的时候 isKindOfClass 方法根本不会执行,而是走到了下面方法中objc_opt_isKindOfClass 主要是因为在llvm中编译时对其进行了优化处理。

// Calls [obj isKindOfClass]
BOOL
objc_opt_isKindOfClass(id obj, Class otherClass)
{
#if __OBJC2__
    if (slowpath(!obj)) return NO;
    Class cls = obj->getIsa();
    //获取isa,
    //如果obj 是对象,则isa是类,
    //如果obj是类,则isa是元类
    if (fastpath(!cls->hasCustomCore())) {
        // 如果obj 是对象,则在类的继承链进行对比,
        // 如果obj是类,则在元类的isa中进行对比
        for (Class tcls = cls; tcls; tcls = tcls->getSuperclass()) {
            if (tcls == otherClass) return YES;
        }
        return NO;
    }
#endif
    return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
}
复制代码
isMemberOfClass

源码分析isMemberOfClass 分为对象方法类方法

// 类方法
// 当前类的元类和传入的类比较
+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}
// 对象方法
// 当前对象的类和传入的类比较
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}
复制代码
BOOL re1 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //
BOOL re2 = [(id)[JCPerson class] isMemberOfClass:[JCPerson class]];     //
BOOL re3 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //
BOOL re4 = [(id)[JCPerson alloc] isMemberOfClass:[JCPerson class]];     //
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
复制代码

输出的结果为:0,0,1,1

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享