一、 objc_class & objc_object
根对象objc_object
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
类 objc_class 继承于 objc_object
struct objc_class : objc_object {
// Class ISA; // 8 字节
Class superclass; // 8 字节
cache_t cache; // 16 字节
class_data_bits_t bits;
class_rw_t *data() const {
return bits.data();
}
}
对象 + 类 + 元类 都有isa , objc_class 继承于 objc_object
总共有16字节,那么通过类对象的地址 + offset(8 + 8 + 16)就可以得到 class_data_bits_t bits; 的地址。
Objective-C 中提供的 class 和 id 其实就是指向 objc_object 的指针, 都属于对象。
typedef struct objc_class *Class;
typedef struct objc_object *id;
cache_t cache 结构体的大小
struct cache_t {
explicit_atomic<struct bucket_t *> _buckets;
// 结构体指针 8 字节
explicit_atomic<mask_t> _mask;
// typedef uint32_t mask_t; 4 字节
#if __LP64__
uint16_t _flags;
// typedef unsigned short uint16_t; 2 字节
#endif
uint16_t _occupied;
// typedef unsigned short uint16_t; 2 字节
}
二、 instance 对象内存分析
@interface Person : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) NSInteger age;
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p1 = [Person alloc];
Person *p2 = [Person alloc];
NSLog(@"p1指向: %@ - p1 内存地址:%p", p1, &p1);
// p1指向: <Person: 0x100404ea0> - p1 内存地址:0x7ffeefbff4a8
NSLog(@"p2指向: %@ - p2 内存地址:%p", p2, &p2);
// p2指向: <Person: 0x100404590> - p2 内存地址:0x7ffeefbff4a0
NSLog(@"hello world");
}
return 0;
}
p1 和 p2 都是 Person 的实例对象,它们是不同的两个对象,分别指向两块不同的内存。
p *p1
(Person) $1 = {
NSObject = {
isa = Person
}
_name = 0x0000000100001010 @"fenglin"
_age = 30
}
(lldb) x/4gx 0x100404ea0
0x100404ea0: 0x001d80010000221d 0x0000000100001010
0x100404eb0: 0x000000000000001e 0x0000000000000000
三、 class对象分析
Class cls1 = [p1 class];
Class cls2 = [p2 class];
Class cls3 = [Person class];
Class cls4 = object_getClass(p1);
Class cls5 = object_getClass(p2);
NSLog(@"cls1-> %p",cls1);
NSLog(@"cls2-> %p",cls2);
NSLog(@"cls3-> %p",cls3);
NSLog(@"cls4-> %p",cls4);
NSLog(@"cls5-> %p",cls5);
// output
cls1-> 0x100002218
cls2-> 0x100002218
cls3-> 0x100002218
cls4-> 0x100002218
cls5-> 0x100002218
cls1 -> cls5 都是 Person 的类对象,为同一个对象,每个类在内存中仅有一个 Class 对象
一些lldb指令:

1、打印实例对象的类对象
(lldb) p/x Person.class
(Class) $0 = 0x00000001000020f0 Person
2、查看类对象的内存分布
x/4gx 0x00000001000020f0
0x1000020f0: 0x00000001000020c8 0x0000000100334140 0x100002100: 0x000000010032e410 0x0000801000000000
3、查看类对象的 isa 指针
// 获取当前的isa
po 0x00000001000020c8
Person
// 通过其他方法获取到Person的元类
p/x object_getClass(Person.class)
(Class) $3 = 0x00000001000021f0
4、查看Person的父类
(lldb) po 0x0000000100334140
NSObject
p/x [objc superclass]
(Class) $4 = 0x0000000100334140 NSObject
5、获取 class_data_bits_t 通过 isa + offset(32) 拿到bits 的地址,再取 * 获取到值
0x00000001000020f0 + 0x20 = 0x100002110
四、meta-class 对象
// 1. 获取类对象
(lldb) p/x Person.class
(Class) $0 = 0x0000000100002570 Person
// 2. 读取类对象的内存结构
(lldb) x/4gx 0x0000000100002570
0x100002570: 0x0000000100002548 0x0000000100334140
0x100002580: 0x000000010032e410 0x0000802400000000
// 3. 打印类对象的 isa 指针
(lldb) po 0x0000000100002548
Person
// 4. 通过runtime-api打印类对象的 isa 指针
(lldb) p/x object_getClass([Person class])
(Class) $3 = 0x0000000100002548
// 5. 测试结果获取到的Person meta-class 内存地址是一致的
// 6. 打印 Person meta-class 的内存结构
(lldb) x/4gx 0x0000000100002548
0x100002548: 0x00000001003340f0 0x00000001003340f0
0x100002558: 0x0000000100657ed0 0x0002e03500000007
// 7. 打印 Person meta-class 的isa ,返回的是 NSObject meta-class
(lldb) po 0x00000001003340f0
NSObject
// 8. 打印bits,通过Person meta-class 的地址 + offset(32)
(lldb) p/x 0x0000000100002568
(long) $6 = 0x0000000100002568
(lldb) p/x (class_data_bits_t *)0x0000000100002568
(class_data_bits_t *) $7 = 0x0000000100002568
// 9. 获取到 class_rw_t
(lldb) p $7.data()
(class_rw_t *) $8 = 0x00000001019043a0
// 10. 获取到Person 类方法
(lldb) p $8.methods()
(const method_array_t) $9 = {
list_array_tt<method_t, method_list_t> = {
= {
list = 0x0000000100002388
arrayAndFlag = 4294976392
}
}
}
// 11. 打印Person 类方法
(lldb) p $9.list.get(0)
(method_t) $11 = {
name = "class_eat"
types = 0x0000000100000e38 "v16@0:8"
imp = 0x0000000100000b70 (KCObjc`+[Person class_eat])
}
网友评论