iOS 类的底层探索(上)
分析类对象内存存在个数
首先,我们创建一个LGPerson类继承于NSObject 通过不同获取类对象的方法来进行验证
Class class1 = [LGPerson class];
Class class2 = [LGPerson alloc].class;
Class class3 = object_getClass([LGPerson alloc]);
NSLog(@"\n%p-\n%p-\n%p",class1,class2,class3);
打印结果:
我们发现 类对象有且只有一个。
isa 流程探索
我们继续用LGPerson这个类来继续如下操作
通过不断地打印isa,我们发现可以总结出:
p对象isa --> LGPerson 类对象
LGPerson 类对象的 isa --> LGPerson 元类对象
LGPerson 元类对象 isa --> NSObject 根元类
NSObject 根元类 isa --> 自己
继承链
我们再来创建一个LGTeacher类继承于LGPerson,通过class_getSuperclass
来获取父类
我们可以看到 LGTeacher
->LGPerson
->NSObject
->nil
元类链
Class teacherMetaClass = objc_getMetaClass("LGTeacher");
NSLog(@"teacher 的元类 %@ - %p",teacherMetaClass,teacherMetaClass);
Class personMetaClass = objc_getMetaClass("LGPerson");
NSLog(@"person 的元类 %@ - %p",personMetaClass,personMetaClass);
Class superTeacherMetaClass = class_getSuperclass(teacherMetaClass);
NSLog(@"teacher 的元类的父类 %@ - %p",superTeacherMetaClass,superTeacherMetaClass);
Class superPersonMetaClass = class_getSuperclass(personMetaClass);
NSLog(@"person 的元类的父类 %@ - %p",superPersonMetaClass,superPersonMetaClass);
Class nsobjectClass = object_getClass(NSObject.class);
NSLog(@"nsobjectClass:%@ - %p",nsobjectClass,nsobjectClass);
打印结果如下:
从打印结果我们可以发现 LGTeacher的元类
->LGPerson的元类
->NSObject
->nil
总结
通过以上的探索可以总结出经典的isa走位图
类结构的分析
首先分析Class
,打开objc
源码发现
typedef struct objc_class *Class;
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
...
}
我们发现类的底层实际上是一个objc_class
结构体
内存偏移
现在我们要探索一下bits存储的数据,isa
(8个字节)superclass
(8个字节),cache_t
(16字节),也就是总共偏移32个字节。
获取bits里面的methodLists
获取bits里面的propertyList
通过lldb
找到了bit
地址
通过源码查看class_data_bits_t
结构
struct class_data_bits_t {
...
class_rw_t* data() const {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
...
}
查看class_rw_t
结构
struct 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 *>(&ro_or_rw_ext)->methods;
} else {
return method_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->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 *>(&ro_or_rw_ext)->properties;
} else {
return property_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->baseProperties};
}
}
...
}
properties()
、 methods()
这两个方法可以获取属性
总结
1.类
在底层实际上是一个结构体objc_class
, objc_class
实际上也是继承objc_object
,所以类
实际上也是对象
2.此次 我们只是对对象
的方法和属性
的存储进行了探究,可以看出对象
的方法
、属性
实际上存在类的class_data_bits_t
的class_rw_t
里面\
下一篇章将继续探索成员变量
存储 类方法
的存储
转载自:https://juejin.cn/post/7089052408852152327