Sobes.tech
Middle+

V jakou dobu a za jakých podmínek začíná v Swift fungovat dispatching?

sobes.tech AI

Odpověď od AI

Řízení metod (method dispatch) v Swift určuje, který přesně kód bude vykonán při volání metody objektu. Výběr typu řízení se děje v momentě kompilace Swift kódu.

Existují tři hlavní typy řízení v Swift:

  1. Přímé řízení (Direct Dispatch):

    • Nejrychlejší.
    • Adresa funkce je známa během kompilace.
    • Používá se ve výchozím nastavení pro:
      • struct a enum (protože nepodporují dědičnost tříd).
      • final metody tříd.
      • private metody tříd (internal a public nepodporují přímé řízení).
      • Globální funkce.
      • Statické metody.
      • Rozšíření (extensions).
  2. Řízení podle tabulky (Table Dispatch):

    • Používá se pro class, když je potřeba polymorfismus a dědičnost.
    • Adresa konkrétní implementace metody je určena za běhu (runtime) pomocí tabulky virtuálních metod (vtable - Virtual Table).
    • Každá třída má svou vtable, obsahující ukazatele na implementace metod.
    • Podporuje dědičnost a přepsání metod.
    class Animal { // Použije Table Dispatch
        func speak() {
            print("Neznámý zvuk")
        }
    }
    
    class Dog: Animal { // Přepsání, používá vtable
        override func speak() {
            print("Wooof")
        }
    }
    
  3. Řízení podle svědectví (Witness Table Dispatch):

    • Používá se pro protokoly (protocol).
    • Podobné table dispatch, ale používá tabulku svědka (witness table) k vyhledání implementace metody protokolu pro konkrétní typ, který odpovídá protokolu.
    • Umožňuje používat polymorfismus s protokoly.
    protocol Speakable { // Použije Witness Table Dispatch
        func speak()
    }
    
    struct Cat: Speakable { // Implementace protokolu
        func speak() {
            print("Mňau")
        }
    }
    

Podmínky ovlivňující výběr:

  • Typ dat: struct, enum, class, protocol.
  • Modifikátory přístupu: final, private, internal, public.
  • Dědičnost: Možnost přepsání metod.
  • Soulad s protokoly: Implementace metod z protokolu.
  • Kontext volání: Volání přes konkrétní typ nebo přes protokol/základní třídu.

Swift compiler se snaží používat přímé řízení, kde je to možné, pro optimalizaci výkonu, ale v případě potřeby podpory polymorfismu a dědičnosti přepíná na table nebo witness table dispatch. Výslovné označení metod jako final nebo private umožňuje vynutit použití přímého řízení.