Static vs Dynamic Dispatch in Swift

以下內容參考自[Ref],這裡僅作個人摘要整理:

Method Dispatch定義:

Method Dispatch是決定runtime實際執行的operation。

Method Dispatch is the mechanism that helps to decide which operation should be executed, or more specifically, which method implementation should be used. (from ref2)

例如:
一個subclass繼承parent class,且override parent class’s部分method。則當subclass的instance在runtime呼叫method時,需決定此時要執行的method是parent class的method或是subclass的method implementation。
Note: 上述內容即為OOP的polymorphism,且method此時屬於Dynamic Dispatch

Method dispatch種類:

  • Inline (Fastest)
  • Static Dispatch
  • Virtual Dispatch
  • Dynamic Dispatch (Slowest)
    Note: method要使用哪一種dispatch機制是由compiler決定

Static Dispatch與Dynamic Dispatch的差別:

  • Static dispatch指的是compiler在compile time就能夠知道要執行method的implementation。
  • Dynamic Dispatch指的是compiler在runtime時才能決定要執行method的哪個implementation。
    Note: 因為在runtime時才會配置object的記憶體空間,所以compiler也只能夠在runtime才能夠去找到實際要執行method的記憶體位置

如何使用Static Dispatch與Dynamic Dispatch?

  • Static Dispatch:
  1. value types
  2. final or static keyword
  • Dynamic Dispatch:
  1. inheritance (subclass and override some methods)

Dynamic Dispatch的種類:

  1. Table Dispatch
  2. Message Dispatch

Table Dispatch:
This dispatch technique makes use of a table, which, is an array of function pointers, called as witness table (or virtual table) to look up for the implementation of a particular method.
Note:
因為compiler需要先從table中去讀取實際要執行的function的memory address,再跳轉到那個function的memory address去執行,所以相對於static dispatch,它需要額外兩個指令,但它仍然比message dispatch來得快。

Message Dispatch:
Instances of a class have an isa pointer, which is a pointer to their class object. The selectors of methods in each object are stored in a “table" in the class object, and the objc_msgSend() function follows the isa pointer to the class object, to the find this table, and checks whether the method is in the table for the class. If it cannot find it, it looks for the method in the table of the class’s superclass. If not found, it continues up the object tree, until it either finds the method or gets to the root object (NSObject). At this point, an exception is thrown.
Note: 使用方式是在method前加上dynamic keyword

class MyClass {
    @objc dynamic func bar() { } // okay
}


ref 1: https://stackoverflow.com/questions/982116/objective-c-message-dispatch-mechanism
ref 2: https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/660630/

Static Dispatch、Table Dispatch、Message Dispatch在程式碼中實際使用例子:

protocol Car {
    func isExpensive() -> Bool // Table
}
class TeslaCar: Car {
    func isExpensive() -> Bool { return true } // Table
    @objc dynamic func addSpeed() { } // Message
}
extension TeslaCar {
    func canFly() -> Bool { return false } // Static
    @objc func lightShow() { } // Message
}
final class UniqueCar {
    func canFly() -> Bool { return true } // Static
}

StaticTableMessage
Explicitly enforcedfinal, static keywordXdynamic
Value typeall methodsXX
Protocolextensionsinitial declarationX
Classextensionsinitial declarationextensions with objc

Ref:

1) https://medium.com/flawless-app-stories/static-vs-dynamic-dispatch-in-swift-a-decisive-choice-cece1e872d

2) https://medium.com/@bakshioye/static-vs-dynamic-dispatch-in-swift-a-decisive-choice-cece1e872d