runtime基本作用
- 在程序运行过程中,动态的创建类,动态添加、修改这个类的方法和属性
- 遍历一个类的所有成员变量、属性、方法
- 消息传递、转发
runtime源码
平时的业务主要使用 官方api解决框架性的需求
对象,类对象,元类对象
- 类对象存储实例方法列表等信息
- 元类对象存储类方法列表等信息
类对象(objc_class)对象结构体
类对象存储实例方法列表等信息
typedef struct objc_class *Class;
OC类是由Class类型表示的,它实际上是一个指向objc_class结构体的指针
查看 objc/runtime.h 中objc_class结构体的定义如下:
struct objc_class{
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
}OBJC2_UNAVAILABLE;
struct objc_class 结构体定义很多变量
结构体里保存了指向父类的指针、类的名字、版本、实例大小、实例变量列表、方法列表、缓存、遵守的协议列表等
- ivars 类中包含所有属性的列表
- cache 主要用于缓存使用过的方法,为了提高了程序方法的运行效率,当我们使用这个类的方法时先判断cache是否为空,为空从methodLists找到调用,并保存到cache,不为空先从cache中找方法,如果找不到在去methodLists
- protocols 列表,这个类都遵守了哪些协议。
一个类就包含以上信息,所以类对象就是一个结构体 struct objc_class,这个结构体存放的数据称为元数据(metadata),
该结构体的第一个成员变量也是isa指针,说明Class本身也是一个对象,因此我们称为类对象,类对象在编译期产生用于创建实例对象,是单例
实例对象(objc_object)
元类对象存储类方法列表等信息
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;
类对象中的元数据存储的都是如何创建一个实例的相关信息,那么类对象和类方法应该从哪里创建呢?
就是从isa指针指向的结构体创建,类对象的isa指针指向元类(metaclass),元类中保存了创建类对象和类方法所需的所有信息,结构图如下所示:

元类(Meta Class)
通过上图看出:
- struct objc_object结构体实例它的isa指针指向类对象,类对象的isa指针指向了元类
- super_class指针指向了父类的类对象,而元类的super_class指针指向了父类的元类
- 元类的isa指针又指向了自己
- 元类(Meta Class)是一个类对象的类
元类(Meta Class)是一个类对象的类。
在上面我们提到,所有的类自身也是一个对象,我们可以向这个对象发送消息(即调用类方法)。
为了调用类方法,这个类的isa指针必须指向一个包含这些类方法的一个objc_class结构体。这就引出了meta-class的概念,元类中保存了创建类对象以及类方法所需的所有信息。
任何NSObject继承体系下的meta-class都使用NSObject的meta-class作为自己的所属类,而基类的meta-class的isa指针是指向它自己。
所以类就是多个结构体组合的一个集合体
网友评论