我在我的类中添加了一个 Timer 变量,并使用它的 didSet 观察者使旧值无效
var timer: Timer? {
didSet { oldValue?.invalidate() }
}
deinit {
timer = nil
}
我认为这足以在类取消初始化时使计时器无效,但看起来 didSet 没有被调用。这是为什么?观察者在去初始化期间不工作吗?
让我们在这里给出一个答案,这样我们就可以结束这个问题了。
看来财产观察员显然不会在
deinit
期间运行。这似乎与属性观察者在 init
期间不运行这一事实平行,但与后者不同的是,前者似乎没有在任何地方明确记录。你可以通过语义欺骗来解决这个问题,但是不要!这似乎是一个错误(我已经提交了)。
最初的用例一开始并不是一个很好的用例。在替换中隐藏计时器的失效听起来像是潜在的维护噩梦。同意失效和替换就像火腿和鸡蛋一样结合在一起,我总是做的是编写一个按顺序失效和替换的方法,并通过该方法汇集所有内容。 (如有必要,可以强制执行,但我不会详细讨论。)可以在
deinit
.补充说明:使用计时器时请注意内存管理问题!你很容易陷入这样一种情况,即
deinit
被 never 调用,因为你保留了计时器,但计时器保留了你。然后,您将无法使计时器无效,并且整个视图控制器将泄漏。您在问题中没有抱怨这一点,但这是一个相关的问题,所以我想我最好标记它。
如果您希望触发 setter,请像这样调用
deinit {
{ timer = nil }()
}
请注意,从 2024 年开始,在
deinit
内设置属性肯定会触发 didSet
。我刚刚亲自验证了这一点。