Dai documenti
Controllo di sicurezza 1
Un inizializzatore designato deve garantire che tutte le proprietà introdotte dalla sua classe siano inizializzate prima di delegare fino a un inizializzatore di superclasse.
Perché abbiamo bisogno di un controllo di sicurezza come questo?
Per rispondere a questo, lascia andare rapidamente il processo di inizializzazione.
Inizializzazione in due fasi
L'inizializzazione della classe in Swift è un processo in due fasi. Nella prima fase, a ciascuna proprietà memorizzata viene assegnato un valore iniziale dalla classe che l'ha introdotta. Una volta determinato lo stato iniziale per ogni proprietà memorizzata, inizia la seconda fase e ogni classe ha la possibilità di personalizzare ulteriormente le proprietà memorizzate prima che la nuova istanza sia considerata pronta per l'uso.
L'uso di un processo di inizializzazione in due fasi rende l'inizializzazione sicura, offrendo comunque la massima flessibilità a ciascuna classe in una gerarchia di classi. L'inizializzazione in due fasi impedisce l'accesso ai valori delle proprietà prima che vengano inizializzati e impedisce che i valori delle proprietà vengano impostati su un valore diverso da un altro inizializzatore in modo imprevisto.
Quindi, per assicurarsi che il processo di inizializzazione in due fasi sia eseguito come definito sopra, ci sono quattro controlli di sicurezza, uno dei quali è,
Controllo di sicurezza 1
Un inizializzatore designato deve garantire che tutte le proprietà introdotte dalla sua classe siano inizializzate prima di delegare fino a un inizializzatore di superclasse.
Ora, l'inizializzazione in due fasi non parla mai di ordine, ma questo controllo di sicurezza, introduce super.init
da ordinare, dopo l'inizializzazione di tutte le proprietà.
Il controllo di sicurezza 1 potrebbe sembrare irrilevante poiché l'
inizializzazione in due fasi impedisce l'accesso ai valori delle proprietà prima che vengano inizializzati , senza questo controllo di sicurezza 1.
Come in questo esempio
class Shape {
var name: String
var sides : Int
init(sides:Int, named: String) {
self.sides = sides
self.name = named
}
}
class Triangle: Shape {
var hypotenuse: Int
init(hypotenuse:Int) {
super.init(sides: 3, named: "Triangle")
self.hypotenuse = hypotenuse
}
}
Triangle.init
ha inizializzato, ogni proprietà prima di essere utilizzata. Quindi il controllo di sicurezza 1 sembra irrilevante,
Ma poi potrebbe esserci un altro scenario, un po 'complesso,
class Shape {
var name: String
var sides : Int
init(sides:Int, named: String) {
self.sides = sides
self.name = named
printShapeDescription()
}
func printShapeDescription() {
print("Shape Name :\(self.name)")
print("Sides :\(self.sides)")
}
}
class Triangle: Shape {
var hypotenuse: Int
init(hypotenuse:Int) {
self.hypotenuse = hypotenuse
super.init(sides: 3, named: "Triangle")
}
override func printShapeDescription() {
super.printShapeDescription()
print("Hypotenuse :\(self.hypotenuse)")
}
}
let triangle = Triangle(hypotenuse: 12)
Produzione :
Shape Name :Triangle
Sides :3
Hypotenuse :12
Qui se avessimo chiamato super.init
prima di impostare il hypotenuse
, la super.init
chiamata avrebbe quindi chiamato il printShapeDescription()
e poiché questo è stato ignorato, ricadrebbe prima sull'implementazione della classe Triangle di printShapeDescription()
. La printShapeDescription()
classe Triangle accede alla hypotenuse
proprietà non facoltativa che non è stata ancora inizializzata. E ciò non è consentito poiché l' inizializzazione in due fasi impedisce l'accesso ai valori delle proprietà prima che vengano inizializzati
Quindi assicurati che l'inizializzazione a due fasi sia eseguita come definito, ci deve essere un ordine specifico di chiamata super.init
e cioè, dopo aver inizializzato tutte le proprietà introdotte dalla self
classe, quindi abbiamo bisogno di un controllo di sicurezza 1