OC底层04:类的结构

2020-09-14  本文已影响0人  ZAREMYDREAM

之前分析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

    总结:

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;
};
  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类信息获取
上一篇下一篇

猜你喜欢

热点阅读