美文网首页APP & program
iOS Runtime之方法查找

iOS Runtime之方法查找

作者: 谢二九 | 来源:发表于2022-06-23 15:14 被阅读0次

    Runtime系列导读

    介绍

    OC是一门动态性比较强的编程语言,允许很多操作推迟到程序运行时再进行。
    OC的动态性就是由Runtime来支撑和实现的,Runtime是一套C语言的API,封装了很多动态性相关的函数平时编写的OC代码,底层都转换成Runtime API(主要是objc_msgSend和objc_msgSendSuper)进行调用。
    我们可以利用Runtime做以下具体场景应用:

    • 关联对象(AssociatedObject)给分类添加属性;
    • 遍历类的所有成员变量;
    • 交换方法实现;
    • 利用消息转发机制解决方法找不到的异常问题

    方法存储

    实例对象与类的关系

    定义

    科普下实例对象(instance)、类(class)、元类(meta-class)。

    • 类在面向对象编程中是一种面向对象计算机编程语言的构造,描述了所创建的对象共同的属性和方法。
    • 实例对象是根据某个类创建的对象。
    • 元类:是一种实例是类的类。

    综上总结,类是实例对象的描述,元类是类对象的描述。

    模型

    实例对象的存储结构(以NSObject实例对象举例):

    struct NSObject_IMP{
      Class isa;
    }
    

    其中,isa是指向NSObject类的指针。

    类对象的存储结构

    struct objc_class {
        Class _Nonnull isa;
        Class _Nullable super_class;
        struct objc_ivar_list * _Nullable ivars;
        struct objc_method_list * _Nullable * _Nullable methodLists;
        struct objc_cache * _Nonnull cache;
        struct objc_protocol_list * _Nullable protocols;
        ...
    }
    

    其中,

    • isa是指向元类的指针
    • super_class是指向父类的指针
    • ivars是指向成员变量的指针
    • methodLists是指向方法列表的指针
    • cache是指向方法缓存的指针
    • protocols是指向协议的指针

    关系

    通过源码分析,可以确认实例对象、类和元类是以下关系:

    • 实例对象的isa指向类
    • 类的isa指向元类
    • 元类的isa指向基类的元类
    • 类的superclass指向父类。如果没有父类,superclass指针为nil
    • 元类的superclass指向父类的元类。基类的元类的superclass指向基类
    • 实例对象调用实例方法,是通过isa找到类,如不存在则通过superclass找父类
    • 类调用类方法,是通过isa找元类,如不存在则通过superclass找父类

    消息发送

    消息发送从类对象或者元类的方法列表缓存和方法列表中查,没有则通过super指针逐级向上,有则缓存并调用。

    动态方法解析

    开发者可以实现以下方法,来动态添加方法实现:

    • +resolveInstanceMethod:
    • +resolveClassMethod:

    动态解析过后,会重新走“消息发送”的流程,“从receiverClass的cache中查找方法”这一步开始执行。

    消息转发

    • a转发给谁处理 - (id)forwardingTargetForSelector:(SEL)aSelector{}
    • b获取方法签名 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{}
    • c自定义转发逻辑 - (void)forwardInvocation:(NSInvocation *)anInvocation{}

    延伸问题

    • 方法模型结构
    • 方法缓存什么场景下会清理
    • NSProxy用法

    相关文章

      网友评论

        本文标题:iOS Runtime之方法查找

        本文链接:https://www.haomeiwen.com/subject/ibavvrtx.html