OC语法
Objective-c语法
Objective-C的本质
- 平时编写的OC代码,底层实现其实都是C/C++代码
1 | Objective-C -> C/C++ -> 汇编语言 -> 机器语言 |
- OC的面向对象都是基于C/C++的数据结构实现的,即 结构体
NSObject的底层实现
1 | @interface NSObject { |
创建一个实例对象,至少需要多少内存?
- 至少需要8个字节
1
2
class_getInstanceSize([NSObjcet class]);
- 至少需要8个字节
创建一个实例对象,实际上分配了多少内存?
- 实际分配了16个字节
- 底层是Buckets size, 16, 32, 48, 64…. 都是16的位数
1
2
malloc_size((__bridge const void *)obj)
OC对象的分类
instance对象(实例对象)
- alloc出来的对象,在内存中存储的信息包括:
- isa指针
- 其他成员变量
- alloc出来的对象,在内存中存储的信息包括:
class对象(类对象)
- 每个类在内存中有且只有一个class对象
- class对象在内存中存储的信息主要包括:
- isa指针
- superClass指针
- 类的属性信息(property)、类的对象方法信息(instance method)
- 类的协议信息(protocol)、类的成员变量信息(ivar)
- ……
meta-class对象(元类对象)
1
Class objectMetaClass = objc_getClass([NSObject class]);//Runtime API
小结:
- objectMetaClass是NSObject的meta-class对象(元类对象)
- 每个类在内存中只有一个meta-class对象
- meta-class对象和class对象的内存结构是一样的,但是用途不一样
主要包括:
1. isa指针
2. superclass指针
3. 类的方法信息(class method)
4. ……
查看Class是否为meta-class,方法:
1
Bool result = class_isMetaClass([NSObjce class]);
isa指针

- instance的
isa指向class- 当调用
对象方法时,通过instance的isa找到class,最后找到对象方法的实现进行调用
- 当调用
- class的
isa指向meta-class- 当调用
类方法时,通过class的isa找到meta-class,最后找到类方法的实现进行调用
- 当调用
** note: ** 从64位开始,isa需要进行一次位运算,才能计算出真实地址
class对象的superclass指针

** note: ** 当student的instance对象要调用Person的对象方法时,会先通过 isa 找到Student的class,然后通过 superclass 找到Person的class,最后找到对象方法的实现进行调用
meta-class对象的superclass指针

** note: ** 当Student的class要调用Person的类方法时,会先通过 isa 找到Student的meta-class,然后通过 superclass 找到Person的meta-class,最后找到类方法的实现进行调用
isa、superclass总结

- instance的isa指向class
- class的isa指向meta-class
- meta-class的isa指向基类的meta-class
- class的superclass指向父类的class
如果没有父类,superclass指针为nil- meta-class的superclass指向父类的meta-class
基类的meta-class的superclass指向基类的class- instance调用对象方法的轨迹
isa找到class,方法不存在,就通过superclass找父类- class调用类方法的轨迹
isa找meta-class,方法不存在,就通过superclass找父类
64位isa指针
- 从64bit开始,isa需要进行一次位运算(isa地址 & ISA_MASK),才能计算出真实地址
1
2
3
4
5
struct objc_class的结构
class、meta-class对象的本质结构都是struct objc_class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize; // instance对象占用的内存空间
uint32_t reserved;
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;
};
struct class_rw_t {
uint32_t flags;
uint32_t version;
const class_ro_t *ro;
method_list_t * methods; // 方法列表
property_list_t *properties; // 属性列表
const protocol_list_t * protocols; // 协议列表
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
};
struct class_data_bits_t {
uintptr_t bits;
public:
class_rw_t* data() {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
};
/* OC对象 */
struct hx_objc_object {
void *isa;
};
/* 类对象 */
struct hx_objc_class : hx_objc_object {
Class superclass;
cache_t cache;
class_data_bits_t bits;
public:
class_rw_t* data() {
return bits.data();
}
hx_objc_class* metaClass() {
return (hx_objc_class *)((long long)isa & ISA_MASK);
}
};用如下方法进行断点查看,内部结构内容
1
2
3
4
5
6
7
8
9
10
11//实例对象
hx_objc_class *studentClass = (__bridge hx_objc_class *)([Student class]);
hx_objc_class *personClass = (__bridge hx_objc_class *)([Person class]);
//类对象
class_rw_t *studentClassData = studentClass->data();
class_rw_t *personClassData = personClass->data();
//元类对象
class_rw_t *studentMetaClassData = studentClass->metaClass()->data();
class_rw_t *personMetaClassData = personClass->metaClass()->data();
参考
李明杰老师课件- objc源码
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ivan's Blog!
评论









