美文网首页
iOS isKindOfClass isMemberOfCla

iOS isKindOfClass isMemberOfCla

作者: fordG | 来源:发表于2020-08-05 10:17 被阅读0次
    • 看了一下runtime记录一下

    下面代码运行结果

    @interface Sark : NSObject
    @end
    @implementation Sark
    @end
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
            BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
            BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
            BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
            NSLog(@"%d %d %d %d", res1, res2, res3, res4);
        }
        return 0;
    }
    
    • 在Object-C中类大部分都是继承自NSObject

    • 我们在调试的过程中发现, isa这个指针


      image.png
    • 在runtime中看源码

    
    /// A pointer to an instance of a class.
    typedef struct objc_object *id;
    struct objc_object {
        Class isa;
    }
    
    /// An opaque type that represents an Objective-C class.
    typedef struct objc_class *Class;
    struct objc_class {
        Class isa  OBJC_ISA_AVAILABILITY;
        #if !__OBJC2__
        Class super_class                                        OBJC2_UNAVAILABLE;
        const char *name                                         OBJC2_UNAVAILABLE;
        long version                                             OBJC2_UNAVAILABLE;
        long info                                                OBJC2_UNAVAILABLE;
        long instance_size                                       OBJC2_UNAVAILABLE;
        struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
        struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
        struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
        struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
        #endif
    } OBJC2_UNAVAILABLE;
    
    //在 objc-runtime-new.h 中
    struct objc_class : objc_object {
        // Class ISA;
        Class superclass;   
        ...
        ...
    }
    
    1. 对象是一个obj_object类型的结构体
    2. 通过上面的代码发现 我们 new 了一个对象,这个对象内部会生产isa指针, 这个指针是指向对象的类,我们就是用这个类来初始化对象的(objc_object)。
    3. isa指针指向的是一个Class类,它的定义是一个ob j_class的结构体,里面存放了很多累的方法成员变量协议等信息, 这里面也有一个isa指针,指向的是这个类的类,从objc_class : objc_object可以看出来, 对象的类本质上也是一个对象, 这里面有一个superclass举个列子分析啊一下
    @interface Person : NSObject
    
    @end
    @implementation Person
    
    
    
    @end
    
    我们初始化一个Person对象
    Person *person = [Person new]
    person对象里面有个isa指针指向Person这个类对象
    Person类对象里面有个isa指针指向Person这个类对象的类, 这个类我们叫做Meta Class 元类
    Person类对象的Meta Class 里面有个superClass我们可以person的父类里面去找他的父类的Meta Class就是Person类对象的isa指针指向的Meta Class的superClass
    
    image.png
    • 最上层的Meta Class的isa指针指向自己,形成一个回路
    • 最上层的NSObject Class的super class指向 nil

    理清楚对象和类对象和元类的关系后再看源码

    + (Class)class {
        return self;
    }
    
    - (BOOL)isKindOf:aClass
    {
        Class cls;
        for (cls = isa; cls; cls = cls->superclass) 
            if (cls == (Class)aClass)
                return YES;
        return NO;
    }
    
    - (BOOL)isMemberOf:aClass
    {
        return isa == (Class)aClass;
    }
    
    • class 返回的类对象本身
    • isKindOf中,我们用类对象本身去和aClass比较, 可以看到首先会拿这个类对象的isa指向的Meta Class 和传入的aClass比较,然后在取Meta Class的superClass再比较一次,然后返回结果
    • isMemberOf直接用方法调用对象的isa指向的类对象来和aClass比较

    题目中 [(id)[NSObject class] isKindOfClass:[NSObject class]]
    方法调用者是[NSObject class] 即NSObject类对象isa指向的MetaClass和[NSObject class]不是同一个,第二次比较的是[NSObject class] 的M etaClass指向的superClass(看上面的图片指向的是[NSObject class] ) 和 [NSObject class] 比较相等,

    [(id)[NSObject class] isMemberOfClass:[NSObject class]] 只比较上面的第一步, 所以不想等

    [(id)[Sark class] isKindOfClass:[Sark class]]; 这个第二部,没有Sark的MetaClass 的superClass指向的是Sark的父类的MetaClass, 所以不可能相等

    [(id)[Sark class] isMemberOfClass:[Sark class]] 同理不想等

    相关文章

      网友评论

          本文标题:iOS isKindOfClass isMemberOfCla

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