如Language Guide - Initialization中所述,Swift 2两阶段类初始化涉及4次安全检查。第四部分如下:
初始化程序无法调用任何实例方法,读取值 任何实例属性,或者将self称为值,直到之后 第一阶段的初始化已经完成。
第一阶段的完成被描述为
Swift中的类初始化是一个两阶段的过程。 在第一个 阶段,每个存储的属性由类分配初始值 介绍它。一旦每个存储属性的初始状态 已确定,第二阶段开始......
现在,请考虑以下示例:
class A {
var a: Int
init() {
a = 2
}
}
class B: A {
var b: Int
override init() {
self.b = 8 // (thanks @vadian)
//First Case: OK
var b = self.b
b += 1
//Second Case: error
var ab = self.a
ab += 1
super.init()
}
}
第二种情况产生预期的编译时错误
在super.init之前使用self进行属性访问是有意义的 因为a未初始化。
但是,第一种情况是有效的。根据安全检查4,它不应该有效,因为我们在第一阶段完成之前使用self 。
这里的结论是什么。安全检查4,如语言指南中所述,不完全正确吗?
答案 0 :(得分:1)
首先,您必须将{8}分配给self.b
,因为编译器会将b
视为局部变量 - 稍后会声明一行 - 抛出此错误
在声明之前使用局部变量'b'
规则是
super
初始化基类的其他实例变量self
所以B级应该是
class B: A {
var b: Int
override init() {
self.b = 8
//First Case
var b = self.b
b += 1
super.init()
//Second Case
var ab = self.a
ab += 1
}
}
我猜编译器在幕后做了类似的事情
let tmp = 8
self.b = tmp
//First Case
var b = tmp