由于 Xcode 10.2 (快速5),defer
范围末尾的deinit
语句产生:
范围结束之前的'defer'语句总是立即执行;替换为“ do”语句以消除此警告
让我们看一下这个例子:
var foo: String {
didSet {
// smt
}
}
deinit {
defer { <--- Warning
foo = bar
}
}
此警告的含义是什么?-在defer
中包含deinit
语句是否合理? (例如,能够触发属性的观察者)。
答案 0 :(得分:4)
该警告是正确的,因为此处使用defer
不会更改程序的执行顺序,这是该语句的设计目的。但是,不幸的是,建议的替代方案否则会改变程序的行为(提交错误:SR-10207)。
值得注意的是,使用defer
来触发属性观察器是一种小技巧,它只能起作用,因为类型检查器认为它与deinit
主体是不同的上下文。您也可以使用闭包表达式实现相同的结果:
deinit {
{ foo = bar }()
}
理想情况下,会有某种形式的语法让您告诉Swift“不要在这里执行直接存储访问”,因此这种变通方法不是必需的,但目前还没有。
>一种不太麻烦的解决方法是将反初始化程序的所需逻辑提取到一个单独的方法中,该方法将逻辑置于正常进行属性访问的上下文中:
class C {
var bar = ""
var foo: String {
didSet {
// smt
}
}
init(foo: String) { self.foo = foo }
private func doDeinit() {
foo = bar
}
deinit {
doDeinit()
}
}