Swift 4、如何删除一个基于块的KVO观察器?

In Swift 4, how do I remove a block-based KVO observer?

如果我这样存储观察者:

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

一旦我不再需要它,我该如何remove/disable/cleanupobserver

我的 foo 实例没有任何接收 NSKeyValueObservation 实例的类似 remove 的方法,observer 本身没有任何 remove-喜欢。

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

另一方面,如果您确实想要注销观察者,请将其从保留它的任何对象中删除,或者告诉它 invalidate。 (一定是有什么东西保留了它,因为如果你不持久化观察者,它会死掉,你的观察者函数将永远不会被调用。)

(你说 "if I store an observer like this",但是你用 let 存储它的方式是一种有点愚蠢的存储观察者的方式。最好把它放在一个集合中您可以稍后将其删除,或者至少将其存储在可选 var 中,您稍后可以将其设置为 nil。)

使用 Swift 5,我开始在核心数据对象上使用 .observe(\.propertyName, ...),因为令牌会在 deinitinvalidate() 调用令牌。

在我最近发现我在泄漏对象之前,它工作得非常好。我看到泄漏的 NSKeyValueObservanceNSKeyValueObservationInfoNSArray 对象。在确认我对令牌的管理是正确的之后,我终于找到了问题所在。

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