Dos documentos
Verificação de segurança 1
Um inicializador designado deve garantir que todas as propriedades introduzidas por sua classe sejam inicializadas antes de delegar um inicializador de superclasse.
Por que precisamos de uma verificação de segurança como esta?
Para responder a isso, vamos rapidamente ao processo de inicialização.
Inicialização bifásica
A inicialização de classe no Swift é um processo de duas fases. Na primeira fase, cada propriedade armazenada recebe um valor inicial pela classe que a introduziu. Depois que o estado inicial de cada propriedade armazenada é determinado, a segunda fase começa e cada classe recebe a oportunidade de personalizar ainda mais suas propriedades armazenadas antes que a nova instância seja considerada pronta para uso.
O uso de um processo de inicialização em duas fases torna a inicialização segura, enquanto ainda oferece flexibilidade completa a cada classe em uma hierarquia de classes. A inicialização em duas fases impede que os valores de propriedade sejam acessados antes de serem inicializados e impede que valores de propriedade sejam configurados para um valor diferente por outro inicializador inesperadamente.
Portanto, para garantir que o processo de inicialização em duas etapas seja realizado conforme definido acima, há quatro verificações de segurança, uma delas é,
Verificação de segurança 1
Um inicializador designado deve garantir que todas as propriedades introduzidas por sua classe sejam inicializadas antes de delegar um inicializador de superclasse.
Agora, a inicialização em duas fases nunca fala sobre ordem, mas essa verificação de segurança é introduzida super.init
após a inicialização de todas as propriedades.
A verificação de segurança 1 pode parecer irrelevante, pois a
inicialização em duas fases impede que os valores das propriedades sejam acessados antes de serem inicializados , sem essa verificação de segurança 1.
Como nesta amostra
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
foi inicializado, todas as propriedades antes de serem usadas. Portanto, a verificação de segurança 1 parece irrelevante,
Mas então pode haver outro cenário, um pouco complexo,
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)
Resultado :
Shape Name :Triangle
Sides :3
Hypotenuse :12
Aqui, se tivéssemos chamado o super.init
antes de definir o hypotenuse
, a super.init
chamada então chamaria o printShapeDescription()
e, uma vez que isso foi substituído, ele retornaria primeiro à implementação da classe Triangle de printShapeDescription()
. A printShapeDescription()
classe of Triangle acessa hypotenuse
uma propriedade não opcional que ainda não foi inicializada. E isso não é permitido, pois a inicialização em duas fases impede que os valores de propriedade sejam acessados antes de serem inicializados.
Portanto, verifique se a inicialização em duas fases é feita conforme definido, precisa haver uma ordem específica de chamada super.init
, ou seja, depois de inicializar todas as propriedades introduzidas pela self
classe, precisamos de uma verificação de segurança 1