Swift与Objective-C中晚调度(Late dispatch)的相关疑问及概念解析
Great question! Let's unpack this clearly to validate your existing understanding and clarify how late dispatch works across these languages.
First, let's confirm your core definition: Late dispatch (often used interchangeably with dynamic dispatch) means a function's existence is checked at compile time (to ensure the class or its parent declares it), but the specific implementation to execute is determined at runtime based on the object's actual type. Your note about C++ using virtual tables for this is spot-on—now let's dive into Swift and Objective-C.
Late Dispatch in Objective-C
Objective-C's entire method-invocation system is built on late dispatch via message sending:
- At compile time, the compiler only verifies that the method signature exists (either on the class or its superclass). It doesn't lock in the implementation address.
- At runtime, the
objc_msgSendfunction uses the object'sisapointer to locate the correct class/metaclass, then looks up the method implementation (first in cache, then in the method list). This system even supports dynamic features like adding methods at runtime or method swizzling—all made possible by late dispatch. - Put simply: almost all instance method calls in Objective-C use late dispatch (unless you use rare edge-case modifiers that bypass it).
Late Dispatch in Swift
Swift balances static type safety with dynamic flexibility, so it supports multiple dispatch modes—including late dispatch:
- Default instance methods (non-final, non-static, non-private): For class methods in an inheritance hierarchy, Swift uses late dispatch by default (via a virtual table-like mechanism, more flexible than C++'s). If a subclass overrides a parent method, the runtime will call the subclass's implementation when the object is of that subclass type.
dynamickeyword: Marking a method asdynamicforces Swift to use Objective-C's message-sending system for late dispatch. This unlocks Objective-C runtime features like KVO, method swizzling, or using@selector.@objc-exposed methods: When you mark a class and its methods with@objc, they become accessible to the Objective-C runtime, which automatically uses late dispatch for those calls.- Note: Swift also uses static dispatch for methods marked
final,static/class(whenfinal), orprivate—these are bound directly at compile time with no runtime lookup.
Is Late Dispatch Exclusive to C++?
Absolutely not! As we've covered, late dispatch is the foundation of Objective-C's dynamic behavior, and Swift supports it extensively for inheritance and dynamic features. Many other languages use late dispatch too: Java's virtual method calls, Python's runtime method lookup, and C#'s virtual methods all follow the same core idea—runtime determination of which implementation to execute based on the object's actual type.
Your initial distinction between Swift's static dispatch and Objective-C's dynamic dispatch is correct, but remember Swift isn't limited to static dispatch—it adapts based on how you define your methods and classes.
内容的提问来源于stack exchange,提问作者DrainOpener

