Runtime

作者: 皮蛋豆腐酱油 | 来源:发表于2019-08-12 17:07 被阅读0次

    一.内容

    SEL
    objc_msgSend函数
    方法缓存

    二.方法编号

    1.oc 选择子表
    2.如果没有找到,自动创建一个SEL,添加到选择子表当中

    三.objc_msgSend函数

    当我们“调用”方法时,在OC中称之为传递消息,对象接收到消息后,会去“方法列表“中寻找,本类中找不到则向上找,如果一直找不到,则进行”消息转发“。那么OC是如何进行消息传递的呢?在OC中,所有的方法底层都是C语言的函数,当我们向一个对象发送一条消息时,编译器会将其转换为一个C函数 objc_msgSend(),这个函数会动态帮我们绑定要执行的函数。

    不是所有的消息传递都会变成objc_msgSend, 还有一些其他的如objc_msgSendSuper, objc_msgSend_stret,取决于当前要发送消息的对象,大部分是objc_msgSend。

    会先查找缓存,没有则会调用objc_msgSend_uncached,objc_msgSend_uncached最终会执行_class_lookupMethodAndLoadCache3,
    _class_lookupMethodAndLoadCache3在runtime当中是有具体实现的。_class_lookupMethodAndLoadCache3最终调用了lookUpImpOrForward

    如果缓存没有命中:

    1. 类对象当中的方法列表查找对象Method_t(method_t.name == sel),如果方法列表有序就二分查找,无序则遍历
    2. 沿着继承链查找当前类对象的方法列表
    3. 消息转发机制
      ①首先动态决议,允许我们动态地添加方法,调用_class_resolveMethod,这个方法里面会判断是不是元类,如果不是,就调_class_resolveInstanceMethod
      ,如果是就调_class_resolveClassMethod,接下来调lookUpImpOrNil,lookUpImpOrNil里面会调lookUpImpOrForward
      ②消息转发
      _objc_msgForward_impcache(触发消息转发机制),分为两部分,forwardTargerForSelector和forwardInvocation
      ③方法缓存
      objc_class:cache_t:buckets_t(是一个散列表)

    四.分类为什么不能添加成员变量

    属性 = get + set + _ivar
    这个变量 _ivar存放在objc_class结构体当中,objc_class在编译时期对于它的成员变量的空间就已经决定好了
    分类是运行时决议的

    相关文章

      网友评论

          本文标题:Runtime

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