之前学了一下Objective-C的Runtime,发现学的不是那么深刻,所以这里写一篇文章,算是边写边学了
概念
OC中加入了很多新的概念,其中主要好似有instace object和class object和meta object,主要是有以下区别
- instance对象(实例对象):instance实例对象就是通过alloc出来的对象,每次调用alloc都会产生新的instance对象
- class对象(类对象):每个类的内存中有且只有一个类对象
- meta-class对象(元类对象):每个类的内存中有且只有一个元类对象
这里说是对象,其实是因为oc everything is object,所以这里抽象成对象了,如果是C++,那么其实就是类,零成本抽象,其实没有那么多区别
在存储的过程中,主要是有以下区别
- 实例对象(instace object)
- isa指针
- 这里主要指向的是类对象
- 其他成员变量
- isa指针
- 类对象(class object)
- isa指针
- 指向的是元类对象
- superClass指针
- 指向的是他的父亲,是类对象的父亲,如果到顶了,那么指向的就是nil
- 类的属性信息(@property),类的对象方法信息(method),类的协议信息(protocol),类的成员变量信息(ivar)
- 存储的是当前的实例方法(也就是 – 开头的方法
- isa指针
- 元类(meta object)
- isa指针
- superClass指针
- 指向的是他的父类,也就是元类对象的父亲,这里有一点不同的是,如果到顶了,那么指向的是基类的class
- 类的属性信息(@property),类的对象方法信息(method),类的协议信息(protocol),类的成员变量信息(ivar)
- 存储的是static的变量和类方法(也就是+开头的方法)。
下面是相关图片的关系


消息发送
oc中的调用方法是在Runtime运行期展开的,而不是像C/C++一样在编译期就确定了,所以之类有点不同,大致的消息转发流程是(不管是instace对象调用还是类方法的调用):
- 先通过isa指针找到对应的类对象,或者是找到对应的meta-class
- 如果是实例方法(instace object)调用,那么先找到对应的类对象(class object),如果是类方法调用,先找到对应的元对象(meta-class object)
- 如果当前找到了,那么就直接执行对应的方法就行了
- 如果没有找到,那么就通过类对象或者实例对象的superClass指针往上找,就是沿着他的父类找,一直找,直到找到为止
- 如果最终找不到,那么就会crash(当然,也有其他补救措施)
- 这里有一点不同的是,注意到meta-class的superClass指针指向的是基类的类对象,那么这时候还会往基类的类对象中找一下,调用一下,如果找不到,就crash。