Swift 2阶段初始化安全检查4

时间:2016-04-06 09:15:57

标签: ios swift

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,如语言指南中所述,不完全正确吗?

1 个答案:

答案 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