最近感觉应该重新看下开源的 Runtime,希望能有更深层的理解,下面几篇都会围绕着runtime来写
对象
OC 中,每一个对象都是一个类的实例,且这个对象的 isa
指针指向它所属的类。
PS:这里留下个坑,因为isa在现有的64位CPU下已经不是一个单纯的指针了,包含了引用计数和weak指向等等信息
随后的一篇我会着重讲写下 isa
相关的东西,飞机票
1 | struct objc_class; |
我们也可以看到49行开始的定义,定义了 Class
和 id
两类型,分别是 objc_class
和 objc_object
类型的指针
类
打开此文件,我们可以找到 OC 中的类的定义 struct objc_class
。 OC 中类也是一个结构体对象,继承了 struct objc_object
ss 。
对象的类:
- 指向的父类对象
- 对象的占用大小
- 成员变量的类型及布局
- 对象可以相应的消息
- 对象实例方法的实现
当我们向对象发送消息时候,这个对象会通过 isa
指针来找到其所属的类是否可以相应消息。
我们可以看一下 OC 中大部分类都继承的 NSObject
这个类, 同样他有个 isa
指针成员变量,也就是说继承它的都会有这个成员变量。
元类
其实每个类也是一个对象,它也是一个类的实例,这个类就是元类。类对象能否响应这个消息也要通过 isa
找到类对象所属的类(元类)才能知道。所以实例方法保存在类中,而类方法保存在元类中。
同时元类也是一个对象,也就是元类对象,元类对象的元类也就是根元类。不过,有一点比较特殊,那就是所有的元类所属的类都是同一个根元类。根元类指的就是根类的元类,具体来说就是根类 NSObject
对应的元类。理论上我们也可以给元类发送消息,但是 OC 倾向于隐藏元类,不想让大家知道元类的存在。元类是为了保持 OC 对象模型在设计上的完整性而引入的,比如用来保存类方法等,它主要是用来给编译器使用的。