Swift的Designated和Convenience初始化器
前言
在Swift中,为了确保类的存储属性都能有一个初始值,提供了几种初始化的方法,接下来将讨论一下Desinated(指定)、Convenience(便捷)初始化器。
Designated(指定)初始化器
之前使用过Objective-C的应该比较了解指定初始化器,很多类都提供了指定初始化器,如UIViewController的为:
- (instancetype)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
,UIView的- (instancetype)initWithFrame:(CGRect)aRect
,其作用是该类或者其子类在初始化的过程中都会调用指定初始化器。当在类中定义指定初始化器时,该初始化器会初始化该类的所有存储属性,且当该类是有父类时,必须调用父类的指定初始化器,注意顺序,先初始化该类自己定义的存储属性,再使用super来调用父类的指定初始化器,跌倒过来编译器会报错。
1 | class RecipeIngredient: Food { |
- 每一个类都必须至少有一个指定初始化器。
Convenience(便捷)初始化器
便捷初始化器需要带一个convenience修饰符,如下代码,在便捷初始化器的定义中,必须先调用其他的初始化器之后,再赋类的存储属性值。
1
2
3convenience init(parameters) {
statements
}便捷初始化器如果重载了父类的指定初始化器,则必须使用override修饰符。
如果子类提供了其父类的所有(注意:必须是所有的)指定初始化器的实现,实现有两种,一种是子类的存储属性都提供了默认值,且没有定义指定初始化器,则会自动集成父类的指定初始化器;另一种是在子类中重新定义,子类中重新定义的方法可以是便捷初始化器,既子类中的便捷初始化器可以重载父类的指定初始化器。这样子类就会自动继承父类的便捷初始化器。
在Extensions中只能添加便捷初始化器。
指定初始化器和便捷初始化器之间的关系
指定初始化器和便捷初始化器之间的3个法则:
- 指定初始化器必须调用其直接父类的指定初始化器。
- 便捷初始化器必须调用该类中其他的初始化器,其初始化器的类型不限。
- 在便捷初始化器的调用链中最后必须调用一个指定初始化器。
最后,直接上官方文档的图示就会对上面的3个规则有比较清晰的认识: