欢迎光临
我们一直在努力

iOS开发函数底层的实现

        iOS开发中,OC与Swift的函数底层实现并不同。

OC

        首先我们来看当OC一个函数进行执行的时候,到底执行了什么。 从汇编层面来观察,当执行一个函数的时候,首先会执行objc_msgSend(receiver,@selector(action)) 如作图中的红框标注的代码所示,但是并没有看到receiver,是因为函数的第一个参数默认存储在X0寄存器中,可以通过打印出来的信息与左侧信息进行对比,发现x0存储的地址就是对象child的地址,也就是参数receiver。

        接下来,可以看到有一个比较receiver是否为nil或者是否为Tagged Pointer的判断(cmp X0, #0)。 其次,对nil与Tagged Pointer的处理,如果是nil则返回0,Tagged的话就用来索引 _objc_debug_taggedpointer_classes 表,找到对应的类,执行LGetIsaDone后的函数。 然后,取出 isa 的真实值,然后去缓存查找 SEL 对应的 IMP, 未命中则进入 objc_msgSend_uncached(慢路径)。 最后,去执行对应的 IMP。

大致总结下OC函数底层的实现如图所示

Swfit

        相较于 OC 主要依赖消息派发,Swift 为了兼顾性能和动态能力,采用了三种函数派发方式。 直接派发是最快的方式。编译期就能确定目标函数,直接调用具体函数地址,常见于 struct、enum、final、private 和协议扩展方法。SIL 中见 function_ref,汇编中常见直接 call。 表派发用于保留一定动态性。普通类方法通过 V-Table 查找,协议要求方法通过 Witness Table 查找,本质是从表中取出函数指针再调用。SIL 中见 class_method 或 witness_method。 消息派发走 OC Runtime,动态性最强,但性能成本也最高。常见于 @objc dynamic。SIL 中见 objc_method,汇编中可以看到 objc_msgSend。

Swift的函数底层执行大致可以总结为下图

赞(0)
未经允许不得转载:171主机测评 » iOS开发函数底层的实现
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址