一.前期准备
下载 objc 源码,创建可断点调试工程,参考下面的文章
github.com/LGCooci/obj…
二、类的 isa 信息
每个 OC 对象, 包括实例对象、类对象、元类对象,都有一个 isa 成员变量, 其中存储了对象的类信息。
测试代码
@interface Person: NSObject
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
// NSObject *objc = [NSObject alloc];
NSLog(@""); // 在此处打上断点
}
return 0;
}
(lldb) x/4gx Person.class // 输出 Person 类对象信息,其中第一个存储的是 isa 信息
0x100002418: 0x00000001000023f0 0x0000000100334140
0x100002428: 0x000000010032e430 0x0000801000000000
(lldb) po 0x00000001000023f0 // Person 类对象的 isa 存储的还是 Person,这个就是 Person 类的元类对象
Person
(lldb) x/4gx 0x00000001000023f0 // 输出 Person 元类对象 isa 信息
0x1000023f0: 0x00000001003340f0 0x00000001003340f0
0x100002400: 0x0000000100708fd0 0x0002e03100000003
(lldb) po 0x00000001003340f0 // Person 元类对象的 isa 是 NSObject
NSObject
(lldb) x/4gx 0x00000001003340f0 // 输出 NSObject 的 isa 信息,可以发现,指向的是其本身
0x1003340f0: 0x00000001003340f0 0x0000000100334140
0x100334100: 0x000000010069d6b0 0x0004e03100000007
(lldb) x/4gx 0x00000001003340f0
0x1003340f0: 0x00000001003340f0 0x0000000100334140
0x100334100: 0x000000010069d6b0 0x0004e03100000007
(lldb)
下面我们再对 NSObject 做验证
(lldb) x/4gx NSObject.class
0x100334140: 0x00000001003340f0 0x0000000000000000
0x100334150: 0x000000010069daf0 0x0001801000000003
(lldb) po 0x00000001003340f0 // NSObject 类对象的 isa 指向一个非本身的 NSObject,这个 NSObject 同上面 Person 元类 isa 指向的是同一个类对象,这个就是 根元类对象
NSObject
(lldb) x/4gx 0x00000001003340f0
0x1003340f0: 0x00000001003340f0 0x0000000100334140
0x100334100: 0x000000010069d6b0 0x0005e03100000007
由上面的实验,可以得出如下结论
三、类的继承关系
父类信息在结构体的位置
// 对象
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
// 类对象
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();
}
// ...
}
从源码中可知,objc_class 结构体对象,使用 x/4gx 命令输出内存信息,第一个 8 字节存储 ISA 变量,第二个 8字节存储 superclass 变量。
验证代码
(lldb) x/4gx Person.class // 输出 Person 类的内存信息
0x100002418: 0x00000001000023f0 0x0000000100334140
0x100002428: 0x000000010032e430 0x0000801000000000
(lldb) po 0x0000000100334140 // Person 类信息的 superclass 是 NSObject
NSObject
(lldb) x/4gx 0x0000000100334140 // 输出 NSObject 类的内存信息
0x100334140: 0x00000001003340f0 0x0000000000000000
0x100334150: 0x000000010069daf0 0x0001801000000003
(lldb) po 0x0000000000000000 // NSObject 类的父类为 nil
<nil>
(lldb) x/4gx 0x00000001000023f0 // 输出 Person 元类的内存信息
0x1000023f0: 0x00000001003340f0 0x00000001003340f0
0x100002400: 0x000000010220df30 0x0005e03100000007
(lldb) po 0x00000001003340f0 // Person 元类的 superclass 与 isa 地址相同,为 NSObject 元类
NSObject
(lldb) x/4gx 0x00000001003340f0 // 输出 NSObject 元类的内存信息,可以看出其 superclass 为 0x0000000100334140,从上面可以的之,这个地址指向 NSObject 类对象
0x1003340f0: 0x00000001003340f0 0x0000000100334140
0x100334100: 0x0000000102104170 0x0006e0310000000f
上述信息可以得出下面的结构
四、isa 和 类的继承 综合
五、类的底层结构
1.类的底层结构图
2.源码
objc_class
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
// 对象结构体
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
// 类对象结构体,继承自 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();
}
// ... 省略方法
}
class_data_bits_t
struct class_data_bits_t {
friend objc_class;
// Values are the FAST_ flags above.
uintptr_t bits;
// ...
class_rw_t* data() const {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
// ...
}
class_rw_t
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint16_t witness;
#if SUPPORT_INDEXED_ISA
uint16_t index;
#endif
explicit_atomic<uintptr_t> ro_or_rw_ext;
Class firstSubclass;
Class nextSiblingClass;
// ...
// 根据 ro_or_rw_ext 类型构建 objc::PointerUnion 类型 ro_or_rw_ext_t
using ro_or_rw_ext_t = objc::PointerUnion<const class_ro_t *, class_rw_ext_t *>;
// 将 ro_or_rw_ext 解析为 ro_or_rw_ext_t 类型,兼容 class_ro_t/class_rw_ext_t
const ro_or_rw_ext_t get_ro_or_rwe() const {
return ro_or_rw_ext_t{ro_or_rw_ext};
}
// 只读信息列表
const class_ro_t *ro() const {
auto v = get_ro_or_rwe();
if (slowpath(v.is<class_rw_ext_t *>())) {
return v.get<class_rw_ext_t *>()->ro;
}
return v.get<const class_ro_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};
}
}
}
objc::PointerUnion
template <class PT1, class PT2>
class PointerUnion {
uintptr_t _value;
static_assert(alignof(PT1) >= 2, "alignment requirement");
static_assert(alignof(PT2) >= 2, "alignment requirement");
struct IsPT1 {
static const uintptr_t Num = 0;
};
struct IsPT2 {
static const uintptr_t Num = 1;
};
template <typename T> struct UNION_DOESNT_CONTAIN_TYPE {};
uintptr_t getPointer() const {
return _value & ~1;
}
uintptr_t getTag() const {
return _value & 1;
}
public:
explicit PointerUnion(const std::atomic<uintptr_t> &raw)
: _value(raw.load(std::memory_order_relaxed))
{ }
PointerUnion(PT1 t) : _value((uintptr_t)t) { }
PointerUnion(PT2 t) : _value((uintptr_t)t | 1) { }
void storeAt(std::atomic<uintptr_t> &raw, std::memory_order order) const {
raw.store(_value, order);
}
template <typename T>
bool is() const {
using Ty = typename PointerUnionTypeSelector<PT1, T, IsPT1,
PointerUnionTypeSelector<PT2, T, IsPT2,
UNION_DOESNT_CONTAIN_TYPE<T>>>::Return;
return getTag() == Ty::Num;
}
template <typename T> T get() const {
ASSERT(is<T>() && "Invalid accessor called");
return reinterpret_cast<T>(getPointer());
}
template <typename T> T dyn_cast() const {
if (is<T>())
return get<T>();
return T();
}
};
class_ro_t
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name;
// 方法列表
method_list_t * baseMethodList;
// 协议列表
protocol_list_t * baseProtocols;
// 变量列表
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
// 属性列表
property_list_t *baseProperties;
// ...
method_list_t *baseMethods() const {
return baseMethodList;
}
// ...
};
class_rw_ext_t
struct class_rw_ext_t {
const class_ro_t *ro;
method_array_t methods;
property_array_t properties;
protocol_array_t protocols;
char *demangledName;
uint32_t version;
};