Sobes.tech
Middle

Jak kompilator znajduje metodę, którą należy wywołać?

sobes.tech AI

Odpowiedź od AI

Kompilator, przetwarzając wywołanie metody:

  • Sprawdza, czy definicja metody istnieje w klasie i jej superklasach.
  • Określa za pomocą statycznego typowania (w czasie kompilacji), jaka metoda powinna zostać wywołana, jeśli to możliwe.

Podczas wykonywania:

  • Używany jest mechanizm dynamicznego dispatchu.
  • Obiekt przechowuje wskaźnik na swoją klasę.
  • Klasa przechowuje tabelę dispatch (method dispatch table), lub vtable w C++/Objective-C, lub tabelę metod (method table) w Swift.
  • Tabela zawiera wskaźniki na implementacje metod.
  • Podczas wywołania metody, środowisko wykonawcze szuka odpowiedniego wpisu w tabeli dispatch klasy obiektu po nazwie selektora (w Objective-C) lub sygnaturze metody (w Swift, dla metod wirtualnych).
  • Po znalezieniu wpisu, wywoływany jest wskaźnik na implementację metody.

W Objective-C wygląda to tak:

// Przykład wywołania metody w Objective-C
// [target messageName:parameter];
// Runtime szuka 'messageName:' w tabeli dispatch 'target'.class

W Swift:

// Przykład wywołania metody w Swift
// instance.methodName(parameter)
// W zależności od typu (final class, struct, protocol, dynamic)
// używa się statycznego lub dynamicznego dispatchu (vtable lub message dispatch)

Typy dispatchu w Swift:

Typ Dispatch Optymalizacja
struct, enum Statyczny Kompilator zna dokładną metodę
final class Statyczny Kompilator zna dokładną metodę
class (nie final) Wirtualny Przez tabelę (vtable)
protocol (bez @objc) Wirtualny Przez tabelę świadków protokołu (protocol witness table)
@objc (class, protocol) Dynamiczny Przez runtime Objective-C (message dispatch)