In Swift tutte le proprietà di tipo non opzionale devono essere inizializzate entro la fine dell'inizializzazione dell'istanza. Per fare ciò, si utilizzano gli inizializzatori: designated (principali), convenience (ausiliari) e required (obbligatori per i sottoclassi).
Esempio:
class Vehicle { let numberOfWheels: Int required init(numberOfWheels: Int) { self.numberOfWheels = numberOfWheels } } class Car: Vehicle { let brand: String // Designated inizializzatore required init(numberOfWheels: Int) { self.brand = "Unknown" super.init(numberOfWheels: numberOfWheels) } // Convenience convenience init() { self.init(numberOfWheels: 4) self.brand = "Ford" } }
Caratteristiche principali:
In quale ordine devono essere inizializzate le proprietà del sottoclasse e della superclasse quando si utilizza l'inizializzatore designated?
Risposta: Tutte le proprietà del sottoclasse devono essere inizializzate prima di chiamare l'inizializzatore designated della superclasse (super.init), altrimenti ci sarà un errore di compilazione. Dopo super.init non è possibile inizializzare nuove proprietà memorizzate del sottoclasse, solo usarle.
class Parent { let parentProp: Int init(prop: Int) { parentProp = prop } } class Child: Parent { let childProp: String init(prop: Int, childProp: String) { self.childProp = childProp // Prima le proprie proprietà super.init(prop: prop) // Poi parent } }
Storia
Uno sviluppatore nel convenience inizializzatore ha cercato di assegnare direttamente un valore a una proprietà richiesta senza chiamare il designated. Di conseguenza, la proprietà è stata inizializzata due volte con valori diversi, il che ha portato a comportamenti imprevisti durante i test.
Storia
Durante l'ereditarietà di una gerarchia di classi profonda, si è dimenticato di dichiarare required init, il che ha portato all'impossibilità di inizializzare correttamente il tipo derivato da un framework tramite reflection, causando un crash durante la deserializzazione del modello JSON.
Storia
Nell'app durante l'estensione della classe Vehicle, non è stato chiamato l'inizializzatore designated della superclasse, il che ha portato a un'inizializzazione errata delle proprietà obbligatorie e a un crash durante il runtime in produzione dopo l'aggiornamento dello schema dei dati.