浅谈Swift派发机制

 更新时间:2021年06月07日 14:21:20   作者:为童沉沦  
派发目的是让 CPU 知道被调用的函数在哪里。Swift 语言是支持编译型语言的直接派发,函数表派发和消息机制派发三种派发方式的,下面分别对这三种派发方式说明下。

直接派发

C++ 默认使用的是直接派发,加上 virtual 修饰符可以改成函数表派发。直接派发是最快的,原因是调用指令会少,还可以通过编译器进行比如内联等方式的优化。缺点是由于缺少动态性而不支持继承。

struct DragonFirePosition {
var x:Int64
var y:Int32
func land() {}
}
 
func DragonWillFire(_ position:DragonFirePosition) {
position.land()
}
let position = DragonFirePosition(x: 342, y: 213)
DragonWillFire(position)

编译 inline 后 DragonWillFire(DragonFirePosition(x: 342, y: 213)) 会直接跳到方法实现的地方,结果就变成 position.land()。

函数表派发

Java 默认就是使用的函数表派发,通过 final 修饰符改成直接派发。函数表派发是有动态性的,在 Swift 里函数表叫 witness table,大部分语言叫 virtual table。一个类里会用数组来存储里面的函数指针,override 父类的函数会替代以前的函数,子类添加的函数会被加到这个数组里。举个例子:

class Fish {
func swim() {}
func eat() {
//normal eat
}
}
 
class FlyingFish: Fish {
override func eat() {
//flying fish eat
}
func fly() {}
}

编译器会给 Fish 类和 FlyingFish 类分别创建 witness table。在 Fish 的函数表里有 swim 和 eat 函数,在 FlyingFish 函数表里有父类 Fish 的 swim,覆盖了父类的 eat 和新增加的函数 fly。

一个函数被调用时会先去读取对象的函数表,再根据类的地址加上该的函数的偏移量得到函数地址,然后跳到那个地址上去。从编译后的字节码这方面来看就是两次读取一次跳转,比直接派发还是慢了些。

消息机制派发

这种机制是在运行时可以改变函数的行为,KVO 和 CoreData 都是这种机制的运用。OC 默认就是使用的消息机制派发,使用 C 来直接派发获取高性能。Swift 可以通过 dynamic 修饰来支持消息机制派发。

当一个消息被派发,运行时就会按照继承关系向上查找被调用的函数。但是这样效率不高,所以需要通过缓存来提高效率,这样查找性能就能和函数派发差不多了。

具体派发

声明

值类型都会采用直接派发。无论是 class 还是协议 的 extension 也都是直接派发。class 和协议是函数表派发。

指定派发方式

  • final:让类里的函数使用直接派发,这样该函数将会没有动态性,运行时也没法取到这个函数。
  • dynamic:可以让类里的函数使用消息机制派发,可以让 extension 里的函数被 override。

派发优化

Swift 会在这上面做优化,比如一个函数没有 override,Swift 就可能会使用直接派发的方式,所以如果属性绑定了 KVO 它的 getter 和 setter 方法可能会被优化成直接派发而导致 KVO 的失效,所以记得加上 dynamic 的修饰来保证有效。后面 Swift 应该会在这个优化上去做更多的处理。

以上就是浅谈Swift派发机制的详细内容,更多关于Swift派发机制的资料请关注脚本之家其它相关文章!

相关文章

  • Swift 中的 Actors 使用及如何防止数据竞争问题(示例详解)

    Swift 中的 Actors 使用及如何防止数据竞争问题(示例详解)

    Swift中的Actors旨在完全解决数据竞争问题,但重要的是要明白,很可能还是会遇到数据竞争,本文将介绍Actors是如何工作的,以及你如何在你的项目中使用它们,感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • swift5.3 UIColor使用十六进制颜色的方法实例

    swift5.3 UIColor使用十六进制颜色的方法实例

    这篇文章主要给大家介绍了关于swift5.3 UIColor使用十六进制颜色的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Swift 中的 JSON 反序列化示例详解

    Swift 中的 JSON 反序列化示例详解

    这篇文章主要为大家介绍了Swift中的JSON 反序列化示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Swift流程控制之循环语句和判断语句详解

    Swift流程控制之循环语句和判断语句详解

    这篇文章主要介绍了Swift流程控制之循环语句和判断语句详解,文中还使用了一个游戏例子来讲解循环语句和判断语句的使用,需要的朋友可以参考下
    2014-07-07
  • Swift读取App的版本信息与PCH文件详解

    Swift读取App的版本信息与PCH文件详解

    这篇文章主要介绍了Swift读取App的版本信息与PCH文件的相关资料,文中通过图文介绍的非常详细,对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • Swift泛型Generics浅析讲解

    Swift泛型Generics浅析讲解

    泛型代码让你能根据你所定义的要求,写出可以用于任何类型的灵活的、可复用的函数。泛型是 Swift 最强大的特性之一,很多 Swift 标准库是基于泛型代码构建的
    2022-08-08
  • 详解在swift中实现NSCoding的自动归档和解档

    详解在swift中实现NSCoding的自动归档和解档

    本篇文章主要介绍了在swift中实现NSCoding的自动归档和解档,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • Swift利用CoreData如何存储多种数据类的通讯录

    Swift利用CoreData如何存储多种数据类的通讯录

    这篇文章主要给大家介绍了关于Swift利用CoreData如何存储多种数据类的通讯录的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧。
    2017-12-12
  • Swift高阶函数contains allSatisfy reversed lexicographicallyPrecedes用法示例

    Swift高阶函数contains allSatisfy reversed lexicographicallyPr

    这篇文章主要为大家介绍了Swift高阶函数contains allSatisfy reversed lexicographicallyPrecedes用法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Objective-C和Swift的转换速查手册(推荐)

    Objective-C和Swift的转换速查手册(推荐)

    这篇文章主要给大家介绍了关于Objective-C和Swift的转换速查手册的相关资料,文中通过示例代码介绍的非常详细,非常推荐给大家参考学习使用,需要的朋友们下面随着小编来一起学习学习不
    2018-06-06

最新评论