Swift 的 派发机制 (Method Dispatch) 有哪几种
在 Swift 中,方法派发(Method Dispatch)指的是在运行时或编译时决定调用哪个函数或方法的机制。Swift 支持多种派发方式,主要包括以下三种:
1. 静态派发(Static Dispatch)
也称为直接派发(Direct Dispatch),是在编译期就确定了要调用的具体方法实现。
- ✅ 优点:性能最好,编译器可以进行内联等优化。
- ❌ 缺点:不支持动态特性(如继承、重写)。
使用场景:
static修饰的方法final修饰的类或方法private方法(隐式 final)- 值类型(
struct、enum)中的方法默认是静态派发 @inlinable的函数
plaintext
struct MyStruct {
func doSomething() { } // 静态派发
}
class MyClass {
static func staticMethod() { } // 静态派发
final func finalMethod() { } // 静态派发
}
2. 虚拟派发 / 动态派发(Dynamic Dispatch / Virtual Table Dispatch)
通过虚函数表(vtable)进行间接调用,适用于类的方法重写。
- ✅ 优点:支持继承和多态。
- ❌ 缺点:比静态派发稍慢,因为需要查表。
使用场景:
class中非final、non-static、non-private、非@objcoverrideable 的方法默认使用 vtable。- class A {
func normalMethod() { } // vtable dispatch
}
class B: A {
override func normalMethod() { } // vtable dispatch (override)
}
plaintext
> 🔍 VTable:每个类维护一个函数指针表,子类会覆盖父类的对应条目。
---
### 3. 消息派发(Message Dispatch / Objective-C Style Dynamic Dispatch)
基于 Objective-C runtime,运行时查找并调用方法,最灵活但性能开销最大。
- ✅ 优点:支持 KVO、Swizzling、动态替换方法等高级特性。
- ❌ 缺点:性能最差。
#### 使用场景:
- `@objc dynamic` 修饰的方法或属性访问器。
- NSObject subclass + @objc method。
- SwiftUI/Combine/KVO/XCTestExpectation/Mock framework(如 OCMock)依赖此机制。
```swift
import Foundation
class MyClass: NSObject {
@objc dynamic func objcDynamicMethod() { }
}
// or even in pure Swift with @objc:
@objc protocol SomeProtocol {
func requiredMethod()
}
extension MyClass: SomeProtocol {
@objc func requiredMethod() { }
}
💡
@dynamicMemberLookup(如 Combine/SwiftUI)也依赖消息机制实现动态成员查找。
📊 Summary Table
| 派发方式 | Mechanism | Performance | Flexibility | Use Case |
|---|---|---|---|---|
| Static | Compile-time binding | Fastest | Low | Structs, final classes, private methods |
| VTable (Virtual) | Runtime table lookup | Medium | High | Class inheritance & overriding |
| Message | ObjC runtime (objc_msgSend) |
Slowest | Highest | Interop with ObjC, KVO, Swizzling |
🧠 Tips for Optimization & Design
- 优先使用值类型和结构体(天然静态派发)。
- 标记不需要重写的类和方法为
final。 - 避免在热路径中使用
@objc dynamic。 - UIKit/SwiftUI/Combine often require
@ObservedObject,@Published, etc., which rely on message dispatch.
✅ Understanding dispatch helps you write more performant and maintainable Swift code!