Middle+
Kada ir kokiomis sąlygomis pradeda veikti Swift dispatching?
sobes.tech AI
Atsakymas iš AI
Metodų paskirstymas (method dispatch) Swift nustato, kuris tiksliai kodas bus vykdomas kviečiant objekto metodą. Pasirinkimas vyksta Swift kodo kompiliacijos metu.
Yra trys pagrindiniai metodų paskirstymo tipai Swift:
-
Tiesioginis paskirstymas (Direct Dispatch):
- Greičiausias.
- Funkcijos adresas žinomas kompiliacijos metu.
- Naudojama pagal numatytuosius nustatymus:
structirenum(nes jie nepalaiko klasių paveldėjimo).finalklasių metodai.privateklasių metodai (internalirpublicnepalaiko tiesioginio paskirstymo).- Globalios funkcijos.
- Statiniai metodai.
- Plėtiniai (extensions).
-
Lentelės paskirstymas (Table Dispatch):
- Naudojama
class, kai reikalingas polimorfizmas ir paveldėjimas. - Konkretaus metodo įgyvendinimo adresas nustatomas vykdymo metu (runtime) naudojant virtualiųjų metodų lentelę (vtable - Virtual Table).
- Kiekviena klasė turi savo vtable, kuriame yra nuorodos į metodų įgyvendinimus.
- Palaiko paveldėjimą ir metodų perrašymą.
class Animal { // Naudoja Table Dispatch func speak() { print("Nežinomas garsas") } } class Dog: Animal { // Perrašymas, naudoja vtable override func speak() { print("Woof") } } - Naudojama
-
Liudytojo lentelės paskirstymas (Witness Table Dispatch):
- Naudojama protokolams (
protocol). - Panaši į table dispatch, bet naudoja liudytojo lentelę (witness table) metodo įgyvendinimui konkrečiam protokolo tipui, kuris atitinka protokolą.
- Leidžia naudoti polimorfizmą su protokolais.
protocol Speakable { // Naudoja Witness Table Dispatch func speak() } struct Cat: Speakable { // Protokoilo įgyvendinimas func speak() { print("Miau") } } - Naudojama protokolams (
Veiksniai, turintys įtakos pasirinkimui:
- Duomenų tipas:
struct,enum,class,protocol. - Prieigos modifikatoriai:
final,private,internal,public. - Paveldėjimas: Galimybė perrašyti metodus.
- Protokolų atitikimas: Metodų įgyvendinimas iš protokolų.
- Kontekstas kvietimo: Kvietimas per konkretų tipą arba per protokolą/bazinę klasę.
Swift kompiliatorius stengiasi naudoti tiesioginį paskirstymą, kur tai įmanoma, optimizacijai, tačiau, jei reikalinga polimorfizmo ir paveldėjimo palaikymas, pereina prie table arba witness table paskirstymo. Aiškus metodų žymėjimas kaip final arba private leidžia priverstinai naudoti tiesioginį paskirstymą.