美文网首页
OC底层04:类的结构

OC底层04:类的结构

作者: ZAREMYDREAM | 来源:发表于2020-09-14 16:00 被阅读0次

    之前分析isa指针,今天具体来分析下类的结构。

    元类

    先创建一个Person类,然后实例化一个对象,然后用LLDB进行分析

    @interface Person : NSObject
    @end
    @implementation Person
    @end
    
    //main中
    NSObject *obj = [NSObject alloc];
    Person *objc1 = [Person alloc];
    
    1. 先来看objc1的isa,上篇已经讲了第一个为isa指针,以及如何获取其绑定的类。objc1对象的isa指针指向Person类


    2. 当我们读取isa指向的这个Person类的内存信息时,会发现他也有个isa,并且指向不同的地址0x0000000100002170
    3. 继续查看,会发现isa任然指向Person


    4. 很明显,这两个Person的地址时不同,这个第二个Person便是元类。


    5. 继续查看这个Person(元类)的isa,我们会发现他指向NSObject(元类)


    6. 为什么说他是元类而不是NSObject呢,因为它与NSObject不同。


    7. NSObject(元类)的isa指向了它自己,并不会往上指,所以它是根,我们叫根元类


    8. 所以我们最后能找到这样的关系。


      isa流程图.png

      总结:

    • 对象isa指向对象的对应的
    • isa指向对应的元类
    • 元类isa指向根元类
    • 根元类isa指向自己

    objc_class & objc_object

    要了解类的结构,就要从起源NSObject开始,查看源码可以发现,NSObject类中有一个Class isa OBJC_ISA_AVAILABILITY

    @interface NSObject <NSObject> {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wobjc-interface-ivars"
        Class isa  OBJC_ISA_AVAILABILITY;
    #pragma clang diagnostic pop
    }
    

    Class是一个结构体指针typedef struct objc_class *Class;
    objc_class继承自objc_object

    struct objc_class : objc_object {
        // Class ISA;
        Class superclass;
        cache_t cache;             // formerly cache pointer and vtable
        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    
        class_rw_t *data() const {
            return bits.data();
        }
        void setData(class_rw_t *newData) {
            bits.setData(newData);
        }
        ……
    }
    

    objc_object主要封装一个对象

    struct objc_object {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    };
    
    • 大部分对象都是继承objc_object来的,根据objc_class的结构,可以通过地址偏移来查找相关类信息。
      对于一个objec_class,根据内存计算方法
    1. isa8个字节
    2. superclass8个字节
    3. cache16个字节
    4. 要获取 bits需要偏移32个字节

      5.objc_class中提供了一个获取类信息的方法class_rw_t *data() const
    5. 阅读class_rw_t,我们会发现他提供了各种类信息相关的方法
        const method_array_t methods() const {
            auto v = get_ro_or_rwe();
            if (v.is<class_rw_ext_t *>()) {
                return v.get<class_rw_ext_t *>()->methods;
            } else {
                return method_array_t{v.get<const class_ro_t *>()->baseMethods()};
            }
        }
    
        const property_array_t properties() const {
            auto v = get_ro_or_rwe();
            if (v.is<class_rw_ext_t *>()) {
                return v.get<class_rw_ext_t *>()->properties;
            } else {
                return property_array_t{v.get<const class_ro_t *>()->baseProperties};
            }
        }
    
        const protocol_array_t protocols() const {
            auto v = get_ro_or_rwe();
            if (v.is<class_rw_ext_t *>()) {
                return v.get<class_rw_ext_t *>()->protocols;
            } else {
                return protocol_array_t{v.get<const class_ro_t *>()->baseProtocols};
            }
        }
    
    1. 我们给Person类添加相应的信息
    @interface Person : NSObject 
    @property (nonatomic, copy) NSString *name;
    - (void)run;
    @end
    @implementation Person
    - (void)run {
        
    };
    @end
    
    1. Person类信息获取

    相关文章

      网友评论

          本文标题:OC底层04:类的结构

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