美文网首页
Swift 派发机制

Swift 派发机制

作者: PierceDark | 来源:发表于2018-05-22 15:41 被阅读35次

此篇博客用来自我学习,来源戴铭大佬的这篇博客

Swift 派发机制

派发目的是让 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)

编译 inlineDragonWillFire(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 的函数表里有 swimeat 函数,在 FlyingFish 函数表里有父类 Fishswim,覆盖了父类的 eat 和新增加的函数 fly

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

消息机制派发

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

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

具体派发

声明

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

指定派发方式

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

派发优化

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

相关文章

  • Swift派发机制

    Swift之所以速度比Object-c快,我觉得跟他的派发机制有关。下面我们聊聊Swift的派发机制。 派发机制分...

  • 浅谈Swift派发机制

    函数的派发机制分为:静态派发(直接派发)、函数表派发、消息派发 1、Swift中所有ValueType(值类型:S...

  • iOS知识复习笔记(16)---swift相关

    一、函数的派发方式 swift函数的派发机制有三类:static直接派发(静态)派发、table函数派发,mess...

  • Swift派发机制

    Swift派发分:静态派发和动态派发 静态派发:(又叫:直接调用) 静态派发机制,同时支持值类型和引用类型;静态派...

  • Swift的函数派发

    前言 对于Swift的学者来说函数派发有很大的误区:就是认为Swift沿用Objective-C的消息派发机制,且...

  • Swift 派发机制

    此篇博客用来自我学习,来源戴铭大佬的这篇博客 Swift 派发机制 派发目的是让 CPU 知道被调用的函数在哪里。...

  • Swift 派发机制

    表格总结如下: 值类型使用直接派发 协议、类的初始化声明使用函数表派发 协议、类的 extension 使用直接派...

  • Swift 派发机制

    https://medium.com/@bakshioye/static-vs-dynamic-dispatch-...

  • Swift - 三种函数派发

    Swift 的函数派发可以分为 静态 和 动态 两种机制,而动态派发又分为 函数表派发 和 消息派发 。 Swif...

  • Swift 函数派发机制

    原文:Method Dispatch in Swift作者:Brian King 派发机制是程序判断如何去调用函数...

网友评论

      本文标题:Swift 派发机制

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