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