Objective-C的本质
- OC代码底层都是C\C++代码
- OC的面向对象都是基于C\C++的数据结构实现的
- OC是结构体
Objective-C对象的内存分配
1.NSObject对象:
- NSObject本质是一个只含有isa指针的结构体,一个isa指针所占内存大小为8个字节,但严格意义上来讲系统会分配16个字节,实际只使用了8个字节,所以也可以说NSObject的占用内存大小就是其isa指针所占内存大小。
- NSObject对象的地址也就是结构体的地址,也就是isa指针的地址
NSObject转成结构体的形式
2.子类对象:
- Student转成结构体如下图:在64位编译器下,一个isa指针为8个字节,由于内存对齐,系统会再分配8个字节,但int类型实际只占用4个字节,所以Student对象占用内存大小为16个字节。
- Student对象的地址也是结构体的地址,即首地址,isa指针的地址。
Student转成结构体的形式
3.验证方法:
- 通过Runtime运行时函数class_getInstanceSize([NSObject class])获取成员变量占用内存的大小。
- 通过导入<malloc/malloc.h>头文件,调用malloc_size((__bridge void *)object)函数获取实际分配内存大小。
- 通过Runtime源码去查看allocWithZone的底层实现,会发现系统会分配不小于16个字节的内存。
- 通过Debug -> Debug Workflow -> View Memory 来查看类的内存地址分配情况。
allocWithZone的底层实现
Debug调试查看内存分配情况
Objective-C对象的分类
1.Objective-C对象,简称OC对象,主要分为三种:
- instance 对象(实例对象)
- class 对象(类对象)
- meta-class 对象(元类对象)
2.instance 对象:
- 通过
[[NSObject alloc] init]
创建出来的对象 - 不同的 instance 对象占据内存不同
- instance 对象在内存中的存储信息包括:isa指针、其他成员变量以及对应的值
3.class 对象:
- 通过
[NSObject class]
创建出来的对象 - 所有的 class 对象都是同一个对象,每个类在内存中有也只有一个 class 对象
- class 对象在内存中的存储信息包括:isa指针、superclass指针、类的属性信息(@property)、类的对象方法信息(instance method)、类的协议信息(protocol)、类的成员变量信息(ivar)
4.meta-class 对象:
- 通过
object_getClass([NSObject class])
创建处理的对象 - meta-class对象是NSObject的元类对象,每个类在内存中也只有一个元类对象
- meta-class对象和class对象的内存结构是一样的,但是用途不一样;
在内存中的存储信息包括:isa指针、superclass指针、类的类方法信息(class method) - 注意:meta-class对象的内存结构也包括属性信息,对象方法信息等,但一般这些信息都是空的,所以可以作为忽略;
[[NSObject class] class]
获取的还是类对象,不是元类对象 - 判断一个对象是否为元类对象,可以通过Runtime函数
class_isMetaClass([NSObject class])
来判断
isa和superClass:
1. isa指针调用方法的过程:
- instance的isa指向class;
当调用对象方法时,通过instance的isa找到class,最后找到对象方法的实现进行调用。 - class的isa指向meta-class;
当调用类方法时,通过class的isa找到meta-class,最后找到类方法的实现进行调用。
isa指针调用方法的过程
2. superclass指针调用方法的过程:
- 当Student的instance对象要调用Person的对象方法时,会先通过isa找到Student的class,然后通过superclass找到Person的class,最后找到对象方法的实现进行调用。
- 当Student的class要调用Person的类方法时,会先通过isa找到Student的meta-class,然后通过superclass找到Person的meta-class,最后找到类方法的实现进行调用。
superclass指针调用对象方法的过程
superclass指针调用类方法的过程
3.总结:
- 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找父类。
Class的本质:
- 从64bit开始,isa需要进行一次位运算,才能计算出真实地址:isa & ISA_MASK
ISA_MASK
- class、meta-class对象的本质结构都是struct objc_class
struct objc_class