Initializer Delegation is een systeem voor delegatie van initialisatie, ingebouwd in Swift voor klassen. In Swift is er historisch gezien een verschil tussen de designated initializer (de belangrijkste initializer van de klasse, verantwoordelijk voor de volledige initialisatie van alle eigenschappen) en de convenience initializer (een hulpfunctie die het maken van een instantie met verschillende sets parameters vergemakkelijkt).
Probleem: als men geen gestructureerde uitvoering van initializers tussen klassen en hun afgeleiden toestaat, bestaat de kans dat de basis klasse niet volledig is geïnitialiseerd, of dat de initialisatie meer dan eens plaatsvindt, wat leidt tot een ongeldige objectstatus.
Oplossing — strikte regel:
Voorbeeld code:
class Vehicle { var wheels: Int // Designated initializer init(wheels: Int) { self.wheels = wheels } // Convenience initializer convenience init() { self.init(wheels: 4) } } class Car: Vehicle { var color: String // Designated initializer init(wheels: Int, color: String) { self.color = color super.init(wheels: wheels) } // Convenience initializer convenience init(color: String) { self.init(wheels: 4, color: color) } }
Belangrijke kenmerken:
Vraag 1: Kan een convenience initializer de initializer van de superklasse rechtstreeks aanroepen via super.init?
Nee, de convenience initializer delegeert altijd de initialisatie aan een andere initializer van dezelfde klasse, die vervolgens de designated initializer van de superklasse kan aanroepen.
Vraag 2: Wat gebeurt er als de vereiste initializer niet in een afgeleide klasse wordt geïmplementeerd?
Als de superklasse een vereiste initializer heeft, moet deze in elke afgeleide klasse worden overschreven (met behulp van required), anders geeft de compiler een foutmelding.
Vraag 3: Wat is het verschil tussen convenience init en convenience required init?
convenience required init is vereist als een specifieke convenience initializer als required in de superklasse is gedeclareerd om de initialisatie in erfelijkheidshierarchieën te ondersteunen.
Een ontwikkelaar heeft super.init aangeroepen vanuit de convenience initializer. De code compileerde alleen dankzij de afwezigheid van bepaalde beperkingen, maar tijdens de uitvoering trad een fout op: niet alle eigenschappen van het object waren geïnitialiseerd.
Voordelen:
Nadelen:
Er werden duidelijk gestructureerde designated en convenience initializers gebruikt met expliciete aanroepen tussen elkaar. De logica werd strikt volgens de regels van Swift aangeroepen, waardoor de initialisatie altijd transparant en correct was.
Voordelen:
Nadelen: