理解 Swift 的方法派发

本文深入探讨Swift中的方法派发,包括静态派发、动态派发和消息派发,以及协议的派发。静态派发在编译时确定,性能最优;动态派发用于实现继承多态,依赖虚函数表;消息派发涉及Objective-C的运行时机制。同时,文章解释了协议派发如何解决类继承的问题,通过存在容器实现对不同类型的支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

派发(dispatch)是一个比较通用的概念,一般是指为了完成某个目的把一个东西发送到某个位置的行为。在计算机科学中,这个术语在很多地方都会用到,比如派发一个调用给某个函数,派发一个事件给一个监听者,派发一个中断给中断处理程序,或者派发一个进程给 CPU。

在这篇文章中,我们主要研究 Swift 中的派发,也就是派发一个调用到某个方法上,Swift 中的方法派发包括类的方法派发和基于协议的派发。

类的方法派发

Swift 中类的方法的派发有以下三种方式:

  • 静态派发(Static Dispatch)
  • 动态派发(Dynamic Dispatch)
  • 消息派发(Messaging Dispatch)

静态派发

静态派发,又叫做早期绑定,是指在编译期将方法调用绑定到方法的实现上,这种派发方式非常快。在编译期,编译器可以看到调用方和被调方的所有信息,直接生成跳转代码,这样在运行期就不会有其它额外的开销。并且编译器可以根据自己知道的信息进行优化,比如内联,可以极大提高程序运行效率。

在 Swift 中,结构体和枚举的方法调用,以及被 final 标记的类和类的方法,都会采用这种派发方式。

动态派发

动态派发是在运行时决定方法调用地址,因此需要有个查找方法地址的机制,在 Swift 中是通过虚函数表(Virtual Method Table),简称 V-Table 实现的,因此动态派发也被称为表派发(Table Dispatch)

在编译期,编译器会给每个包含动态派发方法的类型创建一个虚函数表,这个表会被放在内存的静态区,表中是方法名到方法实现地址的映射。当这个类型的方法被调用时,运行时会去这个类型的虚函数表中寻找这个方法名对应的实现地址,然后再跳转到这个地址执行代码。

动态派发主要是用来实现继承多态,继承多态是多态的一种。例如以下代码:

class Animal {
   
    func makeNoise() {
   
        fatalError("此方法必须通过子类调用")
    }
}

class Dog: Animal {
   
    override func make
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值