类和类结构分析
类的分析
元类
在如下代码中断点调试:
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