美文网首页
isKindOfClass 与 isMemberOfClass

isKindOfClass 与 isMemberOfClass

作者: 开发狗 | 来源:发表于2020-12-20 16:10 被阅读0次

    开篇我们知道有 - (BOOL)isKindOfClass+(BOOL)isKindOfClass-(BOOL)isMemberOfClass 以及 + (BOOL)isMemberOfClass 四种判断方式。

    首先我们编写如下代码:

         BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       
         BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     
         BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];       
         BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];    
     
         BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       
         BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     
         BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];       
         BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];     
    

    +(BOOL)isKindOfClass 与 -(BOOL)isKindOfClass

    前四个为类方法的判断,后四个为对象方法的判断。
    我们使用断点调试,同时打开debug -> Debug Workflow->Always Show Disassembly 查看汇编流程。


    通过断点我们看到与调用+(BOOL)isKindOfClass有关的是执行了objc_opt_isKindOfClass,然后我们在可编译源码文件中查找此方法
    // Calls [obj isKindOfClass]
    BOOL
    objc_opt_isKindOfClass(id obj, Class otherClass)
    {
    #if __OBJC2
        if (slowpath(!obj)) return NO;
        Class cls = obj->getIsa();
        if (fastpath(!cls->hasCustomCore())) {
            for (Class tcls = cls; tcls; tcls = tcls->superclass) {
                if (tcls == otherClass) return YES;
            }
            return NO;
        }
    #endif
        return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
    }
    

    此时我们知道当调用类方法或者实例方法的isKindOfClass时,实际是调用了objc_opt_isKindOfClass,在该方法中我们可以进行研究,根据isa的走位图以及类的继承关系我们可以进行判断,从而得到如下流程。

    +(BOOL)isMemberOfClass 与 -(BOOL)isMemberOfClass

    通过运行可编译文件以及断点调试可以得到如下代码实现

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

    因此可以得到,调用isMemberOfClass的类方法是使用当前调用对象的isa与传入参数类进行对比,根据isa走位,对象的isa 指向,类的isa指向元类,元类的isa指向根元类,根元类的isa指向自身。调用isMemberOfClass的实例方法是使用当前类和传入的类进行判断。

    相关文章

      网友评论

          本文标题:isKindOfClass 与 isMemberOfClass

          本文链接:https://www.haomeiwen.com/subject/jthfwktx.html