我不是罗大锤我不是罗大锤

我不是罗大锤

我不是罗大锤我不是罗大锤

我不是罗大锤

首页首页
分类分类
标签标签
友情链接友情
日记日记
开发中
博客仍在开发中。
Powered byNola
Swift 动态派发与静态派发Swift 动态派发与静态派发

Swift 动态派发与静态派发

&Swift#Swift

允许评论

3 个月前

在 Swift 中,静态派发(Static Dispatch)与动态派发(Dynamic Dispatch)是方法调用的两种机制,对编写高性能代码至关重要。

一、静态派发

定义:在编译时确定调用哪个方法,直接通过内存地址跳转执行,无需运行时查找。但是用静态派发的方法(类)不可重写(继承)。

使用场景:

  • final 定义类或方法。
  • struct 和 enum 的方法默认静态派发。
  • 全局函数或 static 方法。

final 类示例:

final class Calculator {
    func add(a: Int, b: Int) -> Int { a + b } // 静态派发
}

let result = Calculator().add(a: 1, b: 2) // 编译时直接确定调用地址

使用 @inline 内联方法,可以将静态派发优化到机制。

二、动态派发

定义:在运行时通过虚函数表(VTable)查找方法实现,支持继承和方法重写。灵活性更高,支持多态,但是存在性能开销(查表开销)。

使用场景:

  • 非 final 类或方法。
  • @objc 标记的方法(兼容 OC 的动态性)。
  • 协议方法(除非用 extension 提供默认实现且未重写)。

动态派发示例:

class Animal {
    func makeSound() { print("Generic sound") } // 动态派发
}

class Dog: Animal {
    override func makeSound() { print("Bark") } // 运行时决定调用哪个实现
}

let animal: Animal = Dog()
animal.makeSound() // 输出 "Bark"(运行时动态查找)

三、常见问题

  1. 静态派发和动态派发的区别是什么:
    • 静态派发在编译时确定方法地址,直接调用,速度快。
    • 动态派发在运行时通过查表决定时机调用的方法,支持多态但行程稍差。
    • final、struct 默认静态派发,普通类方法和协议通常是动态派发。
  2. 如何优化方法调用的性能:
    • 对不需要继承的类或方法标记 final 启用静态派发。
    • 优先使用 struct 。
    • 避免滥用 @objc 和动态特性。
  3. 为什么 Swift 的协议方法有时是静态派发:
    • 如果协议方法在 extension 中提供默认实现,且未被具体类型重写,编译器会优化为静态派发。
    • 若被重写或协议方法声明在主体中,则 动态派发。
    • Swift 协议的动态派发通过协议见证表(PWT)实现,不同于类的 VTable。
  4. final 关键字除了性能优化还有什么作用:
    • 防止子类以外重写关键逻辑,提升安全性。
    • 明确类设计意图。
  5. 动态派发在底层如何实现:
    • Swift 的类通过虚函数表(VTable)存储方法地址,动态派发时按偏移量查表。
    • OC 的运行时使用消息传递(objc_msgSend),灵活性更高但开销更大。
目录
一、静态派发
二、动态派发
三、常见问题
暂无评论