初始化委托—这是内置于 Swift 中的一种类初始化委托系统。在 Swift 中,指定初始化器(设计初始化器)是负责完全初始化所有属性的类主要初始化器,而便利初始化器是辅助性初始化器,简化了使用不同参数集合创建实例的过程。
**问题:**如果允许类及其子类之间的初始化器混乱执行,可能会出现基本类未被完全初始化,或者初始化进行了多次,导致对象无效的情况。
解决方案是严格的规则:
代码示例:
class Vehicle { var wheels: Int // 指定初始化器 init(wheels: Int) { self.wheels = wheels } // 便利初始化器 convenience init() { self.init(wheels: 4) } } class Car: Vehicle { var color: String // 指定初始化器 init(wheels: Int, color: String) { self.color = color super.init(wheels: wheels) } // 便利初始化器 convenience init(color: String) { self.init(wheels: 4, color: color) } }
关键特点:
问题 1:便利初始化器能否通过 super.init 直接调用超类的初始化器?
不,便利初始化器总是将初始化委托给当前类的另一个初始化器,后者可以调用超类的指定初始化器。
问题 2:如果不在子类中实现所需的初始化器,会发生什么?
如果超类有所需的初始化器,则必须在每个子类中重写它(使用 required),否则编译器将抛出错误。
问题 3:便利 init 和便利所需 init 之间有什么区别?
便利所需初始化器 是必需的,如果超类中将特定便利初始化器声明为所需,以确保在继承层次中支持初始化。
开发者在便利初始化器中调用了 super.init。代码之所以能编译是因为缺少某些限制,但在执行时发生了错误:并非所有对象属性都被初始化。
优点:
缺点:
使用结构清晰的指定和便利初始化器,明确彼此调用。逻辑严格遵循 Swift 的规则,确保初始化始终清晰且正确。
优点:
缺点: