美文网首页
OC底层_类结构分析

OC底层_类结构分析

作者: nicedayCoco | 来源:发表于2020-09-14 19:26 被阅读0次

    类和类结构分析

    类的分析

    元类

    在如下代码中断点调试:

    int main(int argc, char * argv[]) {
        @autoreleasepool {
            LGPerson *person = [LGPerson alloc];
            LGTeacher *teacher = [LGTeacher alloc];
            
    //        Class class = object_getClass([LGPerson alloc]);
    
            NSLog(@"......%@...%@..",person,teacher);
        }
        return 0;
    }
    
    (lldb) x/4gx person
    0x6000019303e0: 0x0000000100ea96f8 0x0000000000000000
    0x6000019303f0: 0x0000000000000000 0x0000000000000000
    (lldb) p/x 0x0000000100ea96f8 & 0x00007ffffffffff8ULL
    (unsigned long long) $1 = 0x0000000100ea96f8
    (lldb) po 0x0000000100ea96f8
    LGPerson
    
    
    

    元类系统给的,其定义创建都是由编译器完成,在这个过程中,归属来自于元类

    元类类对象,每个都有一个独一无二的元类用来存储类方法的相关信息`。

    元类本身是没有名称的,由于与关联,所以使用了同类名一样的名称

    • 对象isa 指向 (也可称为类对象
    • isa 指向 元类
    • 元类isa 指向 根元类,即NSObject
    • 根元类isa 指向 它自己
    img

    元类的说明

    NSObject 分析

    根元类是NSObject , 那根元类到底有几个?

    验证方式一

    通过 lldb 命令

    (lldb) x/4gx person.class
    0x100ea96f8: 0x0000000100ea96d0 0x0000000101787200
    0x100ea9708: 0x0000600000c2c3c0 0x0002802400000003
    (lldb) x/4gx 0x0000000100ea96d0
    0x100ea96d0: 0x00000001017871d8 0x00000001017871d8
    0x100ea96e0: 0x0000600003714400 0x0001c03500000007
    (lldb) p/x 0x00000001017871d8 & 0x00007ffffffffff8ULL
    (unsigned long long) $7 = 0x00000001017871d8
    (lldb) po 0x00000001017871d8
    NSObject
    

    验证方式二

    通过代码验证

    Class class1 = [LGPerson class];
            Class class2 = [LGPerson alloc].class;
            Class class3 = object_getClass([LGPerson alloc]);
            
            NSLog(@"class...\n %p \n %p \n %p",class1,class2,class3);
            
            
    打印结果:        
    2020-09-14 17:02:35.668333+0800 test[8581:8170698] class...
     0x10ee85700 
     0x10ee85700 
     0x10ee85700
    
    

    所以 NSObject 只存有一份

    对象,类,元类,根元类的关系

    isa 指向关系

    实例对象(Instance of Subclass)`的 `isa` 指向 `类(class)
    类对象(class)` `isa` 指向 `元类(Meta class)
    元类(Meta class)`的`isa` 指向 `根元类(Root metal class)
    根元类(Root metal class)` 的`isa` 指向它`自己`本身,形成`闭环`,这里的`根元类`就是`NSObject
    

    继承关系

    之间 的继承关系:

    • 类(subClass) 继承自 父类(superClass)
    • 父类(superClass) 继承自 根类(RootClass),此时的根类是指NSObject
    • 根类 继承自 nil,所以根类NSObject可以理解为万物起源,即无中生有

    元类也存在继承,元类之间的继承关系如下:

    • 子类的元类(metal SubClass) 继承自 父类的元类(metal SuperClass)
    • 父类的元类(metal SuperClass) 继承自 根元类(Root metal Class
    • 根元类(Root metal Class) 继承于 根类(Root class),此时的根类是指NSObject

    objc_class 和 objc_object

    源码分析

    使用clang编译main.m文件

    struct NSObject_IMPL {
        Class isa;
    };
    
    typedef struct objc_class *Class;
    

    在objc4源码中搜索objc_object

    struct objc_object {
        Class _Nonnull isa __attribute__((deprecated));
    };
    

    两者关系

    img

    内存偏移

    普通指针

    img

    对象指针

    img

    数组指针

    img

    类信息

    struct objc_class : objc_object {
        // Class ISA; //8字节
        Class superclass; //Class 类型 8字节
        cache_t cache;             // formerly cache pointer and vtable
        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
        
        //....方法部分省略,未贴出
    }
    

    相关属性

        isa属性:继承自objc_object的isa,占 8字节
    
        superclass 属性:Class类型,Class是由objc_object定义的,是一个指针,占8字节
    
        cache属性:简单从类型class_data_bits_t目前无法得知,而class_data_bits_t是一个结构体类型,结构体的内存大小需要根据内部的属性来确定,而结构体指针才是8字节
    
        bits属性:只有首地址经过上面3个属性的内存大小总和的平移,才能获取到bits
    
    
    
    
    

    cachat_t

    bits

    img

    property_list

    img

    methods_list

    img

    参考 :
    链接:https://www.jianshu.com/p/873e530a0995

    相关文章

      网友评论

          本文标题:OC底层_类结构分析

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