【发布时间】:2019-03-20 02:40:16
【问题描述】:
我在我的类中添加了一个 Timer 变量,并使用它的 didSet 观察者使旧值无效
var timer: Timer? {
didSet { oldValue?.invalidate() }
}
deinit {
timer = nil
}
我认为当类被取消初始化时这足以使计时器无效,但看起来没有调用 didSet。这是为什么?观察者在反初始化期间是否不工作?
【问题讨论】:
-
很好的观察!显然你是对的,而且它是有道理的(我们不想在取消初始化期间触发副作用),但我没有看到任何地方清楚地记录它。
-
不是您问题的答案。但是为了避免混淆和方便阅读,最好只调用
timer.invalidate()(这样运行循环会删除它的指针),然后在对象本身释放时,计时器也会被删除。我的意思是在将您的计时器设置为nil并在其上调用invalidate之间,失效要重要10 倍...... -
我提交了一个错误,因为事实证明您可以通过使用
defer解决这个问题,这应该是不可能的。 -
@Hamish “你可以逃避语义分析” 对,我建议你不应该这样做。但我不认为这些案例是相同的。将某些事情推迟到初始化之后是连贯的,因为我们现在已经初始化了。在取消初始化之后推迟某些事情简直是疯了。
-
@matt “在初始化之后推迟某些事情是一致的,因为我们现在已经初始化了”——当然,我同意这是完全合理的,但是当前的直接存储逻辑并没有区分“不”尚未初始化”和“已初始化”,例如gist.github.com/hamishknight/4af8509b0eaf889ff763770949e8920a。可以说,这个模型比第二次访问是非直接的模型更简单、更容易推理。但我确实认为
defer应该与这个模型保持一致,即它应该与我的示例中的第二个访问具有相同的访问语义。
标签: swift deinit property-observer