runtime之动态添加方法(动态决议,请求转发)

来源:互联网 发布:安卓新版淘宝指纹支付 编辑:程序博客网 时间:2024/05/15 12:40
runtime中实例变量调用方法的步骤
1.在该实例变量的方法缓存列表中查找方法,如果找到就执行。
2.如果没找到,会在该类结构的方法列表中查找该方法,如果找到就执行。
3.如果没找到,会在该类的父类重复步骤1、2。
4.如果知道根类没找到,就会报错:unrecognized selector sent to instance 0x1005046c0.

解释:
类结构:
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
    Class super_class                       OBJC2_UNAVAILABLE;  // 父类
    const char *name                        OBJC2_UNAVAILABLE;  // 类名
    long version                            OBJC2_UNAVAILABLE;  // 类的版本信息,默认为0
    long info                               OBJC2_UNAVAILABLE;  // 类信息,供运行期使用的一些位标识
    long instance_size                      OBJC2_UNAVAILABLE;  // 该类的实例变量大小
    struct objc_ivar_list *ivars            OBJC2_UNAVAILABLE;  // 该类的成员变量链表
    struct objc_method_list **methodLists   OBJC2_UNAVAILABLE;  // 方法定义的链表
    struct objc_cache *cache                OBJC2_UNAVAILABLE;  // 方法缓存
    struct objc_protocol_list *protocols    OBJC2_UNAVAILABLE;  // 协议链表
#endif
} OBJC2_UNAVAILABLE;

实例变量的方法缓存列表:常用的方法存在cache列表中,这样查找效率高,如果cache中查找不到,再在methodList中查找,找到后,把方法添加到cache中。在父类中找到方法,添加到自己的cache列表中,而不会添加到methodList中。
类结构的方法列表:methodList,存储该类所有方法。

也就是说
1、重写父类的方法,本质上不是覆盖了父类的方法,只不过是在本类中找到相应的方法,不再去父类中查找方法而已。(即在本类的methodList方法中,添加该方法)
2、super关键字并不是指父类,作用是 跳过此类直接从父类中进行查找方法

动态决议以及请求转发就是拦截上述过程,让其在runtime中运行相应的方法。

动态决议:
请求转发:
如果动态决议和请求转发都实现了,那么动态决议的优先级要高于请求转发.
原创粉丝点击