虽然咱们很少有机会用到关于Runtime这种非常底层的api,但是面试官们也是一点都这样觉得!!
一,什么是runtime、
1)在程序的运行过程中都会被转化成runtime的c代码执行
2)oc一切都被设计成了对象,实际上类的本质也是一个对象,属于class类实例
在runtime中用结构体表示如下
//描述类中的一个方法
typedef struct objc_method *Method;
//描述实例变量
typedef struct objc_ivar *Ivar;
// 类别
typedef stuck objc_category *Category;
//类中声明属性
typedef struct objc_property *objc_property_t;
类在runtime中的表示
struct objc_class{
Class isa;//指针,对象的isa指针指向所属类,类的isa指针指向父类
Class super_class;//只向父类;
const char *name;//类名
struct objc_ivar_list *ivars;//成员变量表
struct objc_method_list *methodLists;//方法列表
struct objc_cache *cache;//缓存
//这是一种优化,调用过的方法进入缓存表,下次调用先去缓存中寻找
}
二,获取列表
runtime提供了一些方法来获取类的信息,比如属性列表。方法列表。成员变量列表和遵循的协议列表。有时候我们需要给模型的属性赋值的时候,就可以用到。
三,方法调用过程(消息发送过程)
1,将消息发给对象,在对象中的缓存方法中寻找方法,如果找到,转向相应的方法并执行
2,如果没找到,通过对象的isa指针找到所属类,在类中的列表中找到调用的方法,如果找到则执行
3,如果没有找到,去所属类的isa指针指向的父lei中招到方法,并执行
4,如果一直找到跟类都没有这个消息的方法,转向拦截调用(这里指消息的转发,需要重写方法,如果对象1的跟类都没有执行,则由对象2中去寻找并执行);
5,如果没有重写拦截调用的方法,程序则报错