La Delegación de Inicializadores es un sistema de delegación de inicialización incorporado en Swift para clases. En Swift, históricamente se ha establecido una distinción entre el inicializador designado (el inicializador principal de la clase, responsable de la inicialización completa de todas las propiedades) y el inicializador de conveniencia (un ayudante que facilita la creación de una instancia con diferentes conjuntos de parámetros).
Problema: si se permite la ejecución caótica de inicializadores entre clases y sus herederos, no se puede excluir la situación en la que la clase base no esté completamente inicializada, o la inicialización se realice más de una vez, lo que lleva a un objeto inválido.
La solución es una regla estricta:
Ejemplo de código:
class Vehicle { var wheels: Int // Inicializador designado init(wheels: Int) { self.wheels = wheels } // Inicializador de conveniencia convenience init() { self.init(wheels: 4) } } class Car: Vehicle { var color: String // Inicializador designado init(wheels: Int, color: String) { self.color = color super.init(wheels: wheels) } // Inicializador de conveniencia convenience init(color: String) { self.init(wheels: 4, color: color) } }
Características clave:
Pregunta 1: ¿Puede un inicializador de conveniencia llamar al inicializador de la clase base directamente a través de super.init?
No, el inicializador de conveniencia siempre delega la inicialización a otro inicializador de la clase actual, que posteriormente puede llamar al inicializador designado de la clase base.
Pregunta 2: ¿Qué sucederá si no se implementa el inicializador requerido en la subclase?
Si la clase base tiene un inicializador requerido, debe ser sobreescrito en cada subclase (usando required), de lo contrario, el compilador generará un error.
Pregunta 3: ¿Cuál es la diferencia entre convenience init y convenience required init?
convenience required init es necesario si un inicializador de conveniencia específico se declara como requerido en la clase base para asegurar el soporte de inicialización en jerarquías de herencia.
Un desarrollador llamó a super.init desde el inicializador de conveniencia. El código se compiló solo debido a la ausencia de ciertas restricciones, pero en el momento de la ejecución surgió un error: no todas las propiedades del objeto estaban inicializadas.
Ventajas:
Desventajas:
Se utilizaron inicializadores designados y de conveniencia claramente estructurados con llamadas explícitas entre ellos. La lógica se activaba estrictamente según las reglas de Swift, por lo que la inicialización siempre era transparente y correcta.
Ventajas:
Desventajas: