关于初始化的具体内容请查看官方文档。
下面标出几个关键点:
Swift中的初始化方法统称为初始化器
-
和OC不同,Swift中的类、枚举、结构体都可以有构造器,并且Swift中的构造器没有返回值,例如
// 没有返回值,也没有func关键字 init() { // perform some initialization here }
-
Swift还为类提供了便利构造器,枚举和结构体没有
convenice init(parameters) { statements }
类和结构体必须在初始化完成之前设置所有存储属性的默认值,可以在初始化时直接设置或者在初始化器中设置。如果有的存储属性从逻辑来说可以是空值,那么可以通过声明为可选值来避免初始化为确定的值,比如:
class SurveyQuestion {
var text: String
var response: String?
init(text: String) {
self.text = text
}
func ask() {
print(text)
}
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
cheeseQuestion.ask()
// Prints "Do you like cheese?"
cheeseQuestion.response = "Yes, I do like cheese.
- 如果一个类或结构体没有自定义的构造器并且他的所有属性都有默认值,那么,Swift会为它们提供默认的构造器。
对于类来说,这些类必须是基类。不然,如果子类和父类都没有任何自定义的构造器,也没办法区分子类是继承了父类的默认初始化构造器还是Swift提供的默认构造器,因为这两种情况看起来是一样的。
- 初始化构造器和其他函数一样默认以参数类型作为标签,如果在调用的时候不想使用参数标签可以只用
_
来显示的忽略标签。 - 如果结构体没有任何的自定义构造器,那么Swift会为它提供一个默认的成员构造器。如果结构体所有的存储属性都有默认值,那么在初始化这个结构体的时候可以调用无参构造器(会有警告但不会报错);如果其中一个存储属性没有默认值,那么必须调用成员构造器,否则会报错。
成员构造器:结构体中,以结构体成员作为参数的构造器
- 如果提供了自定义的构造器,那么默认构造器将不复存在
包括结构体的成员构造器,所以,如果为结构体提供自定义构造器,请确保结构体中的所有存储属性在初始化完成之前都有值了,否则会报错
- 针对第7点,可以使用Extension来增加自定义构造器,避免默认构造器无法使用
- 类、结构体必须至少有一个指定构造器(默认会有一个),并且通常也只有一个
- 类可以没有便利构造器
- 类的构造器器代理
- 指定构造器必须调用直接父类的指定构造器
- 便利构造器必须调用本类中的其他构造器
- 便利构造器最终必须调用本类的指定构造器
值类型(结构体、枚举)中的指定构造器可以调用本类中的指定构造器,但是引用类型(类)中的指定构造器只能调用直接父类的指定构造器
- 对于两段初始化(Two-Phase Initialization)这里只有一点要提醒:只有当整个继承链上的所有类的属性都被初始化以后,才能使用
self
- 初始化器的继承:
- Swift中,子类默认不会继承父类的构造器器
- 使用
override
关键字来重写父类的构造器 - 子类不能继承父类的便利构造器
- 子类可以修改父类的变量属性(父类初始化完成以后),但是不能修改常量属性,因为父类的常量在父类初始化过程中已经有值了,常量一经赋值不能更改
- 如果子类没有自定义任何的指定构造器方法(便利构造器可有可无)或者重写了(可以通过指定构造器或者便利构造器重写)父类的所有指定构造器方法,那么子类就会自动继承父类的所有构造器方法(包括指定构造器和便利构造器)
- 对于可失败的构造器,使用
init?
表示构造器可能失败,在可能失败的情况下return nil
否则,不要return
struct Animal {
let species: String
init?(species: String) {
if species.isEmpty { return nil }
self.species = species
}
}
就说到这里吧,后面还有一些用法请参考具体文档
虽然不多,也写了一下午,把这块的文档看了3遍。如果对你有用,请点个赞吧。有问题请留言,尽快回复。谢谢。