在Swift 4中,如何删除基于块的KVO观察者?

时间:2017-10-05 17:33:21

标签: swift key-value-observing swift4

如果我存储这样的观察者:

let observer: NSKeyValueObservation = foo.observe(\.value, options: [.new]) { (foo, change) in
    print(change.newValue)
}

如果我不再需要它,如何删除/禁用/清除observer

我的foo个实例没有任何remove类似方法接收NSKeyValueObservation个实例,observer本身没有任何remove - 像其中一样。

2 个答案:

答案 0 :(得分:28)

在iOS 11中,您不必这样做。只是让观察者超出范围。在观察者面前让观察者死亡或者让观察者死于观察者死亡之前不再有任何惩罚,所以你没有实际的工作要做。

另一方面,如果你真的希望取消注册观察者,请将其从保留它的内容中删除,或者将其告诉invalidate。 (必须保留它,因为如果你不坚持观察者,它将会死亡并且你的观察者函数永远不会被调用。)

(你说"如果我存储像这样的观察者",但你用let存储它的方式,对于存储观察者来说是一种有点愚蠢的方式。将它放在一个集合中,您可以在以后将其删除,或者至少将其存储在您可以稍后设置为var的可选nil中。)

答案 1 :(得分:1)

使用 Swift 5,我开始在核心数据对象上使用 .observe(\.propertyName, ...),因为令牌会在 deinitinvalidate() 调用时自动注销令牌。< /p>

这非常有效,直到我最近注意到我正在泄漏对象。我看到泄漏的 NSKeyValueObservanceNSKeyValueObservationInfoNSArray 对象。在确认我正确管理令牌后,我终于找到了问题。

如果您对 Core Data 对象执行 .observe(),则必须保留该对象以及令牌。如果在您使/释放令牌之前对象变成错误,您将泄漏内存。你不会崩溃,但一旦它变成一个错误,即使你释放了令牌,你也会泄漏内存。