我可以在 deinit 中使用 didSet 吗?

问题描述 投票:0回答:3

我在我的类中添加了一个 Timer 变量,并使用它的 didSet 观察者使旧值无效

var timer: Timer? {
    didSet { oldValue?.invalidate() }
}

deinit {
    timer = nil
}

我认为这足以在类取消初始化时使计时器无效,但看起来 didSet 没有被调用。这是为什么?观察者在去初始化期间不工作吗?

swift deinit property-observer
3个回答
11
投票

让我们在这里给出一个答案,这样我们就可以结束这个问题了。

  • 看来财产观察员显然不会在

    deinit
    期间运行。这似乎与属性观察者在
    init
    期间不运行这一事实平行,但与后者不同的是,前者似乎没有在任何地方明确记录。

  • 可以通过语义欺骗来解决这个问题,但是不要!这似乎是一个错误(我已经提交了)。

  • 最初的用例一开始并不是一个很好的用例。在替换中隐藏计时器的失效听起来像是潜在的维护噩梦。同意失效和替换就像火腿和鸡蛋一样结合在一起,我总是做的是编写一个按顺序失效和替换的方法,并通过该方法汇集所有内容。 (如有必要,可以强制执行,但我不会详细讨论。)可以在

    deinit
    .

  • 期间调用该方法

补充说明:使用计时器时请注意内存管理问题!你很容易陷入这样一种情况,即

deinit
never 调用,因为你保留了计时器,但计时器保留了你。然后,您将无法使计时器无效,并且整个视图控制器将泄漏。您在问题中没有抱怨这一点,但这是一个相关的问题,所以我想我最好标记它。


0
投票

如果您希望触发 setter,请像这样调用

deinit {
    { timer = nil }()
}

0
投票

请注意,从 2024 年开始,在

deinit
内设置属性肯定会触发
didSet
。我刚刚亲自验证了这一点。

© www.soinside.com 2019 - 2024. All rights reserved.