类和类结构分析
类的分析
元类
在如下代码中断点调试:
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
指向 它自己
元类的说明
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));
};
两者关系
内存偏移
普通指针
对象指针
数组指针
类信息
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