swift - 尝试删除 KVO 观察器时崩溃

标签 swift swift3 key-value-observing

我是第一次实现 KVO,在某些情况下,它可以正常工作并且可以正确调用 observeValue。但是,当我试图在 deinit 中删除观察者时遇到了崩溃:

Cannot remove an observer for the key path "downloadInProgress" from because it is not registered as an observer.

...虽然我确实在 viewDidLoad 中注册了对象。

// At the top of my file
dynamic var downloadInProgress: Bool = false


override func viewDidLoad() {
    super.viewDidLoad()
    self.addObserver(self, forKeyPath:  #keyPath(downloadInProgress), options: [.old,.new], context: nil)
}

deinit {
    // It crashes here
    removeObserver(self, forKeyPath: #keyPath(downloadInProgress))
}

基本上如果 downloadInProgress = false,它就会崩溃。我究竟做错了什么?谢谢。

最佳答案

你写的

// At the top of my file
dynamic var downloadInProgress: Bool = false

所以它不是对象的一部分?如果是这样,那可能是问题所在。 KeyValueObserving 是 ObjectiveC 的一项技术。在 Swift 中,它有一些限制。一个限制是它只适用于从 NSObject 派生的类。如果它是我期望的全局变量,则不会实现。

Apple documentation :

You can use key-value observing with a Swift class, as long as the class inherits from the NSObject class

如果你有一个像这样的 kvo 对象,它应该可以工作:

final class MyObject: NSObject {
   dynamic var downloadInProgress: Bool = false
}

self.addObserver(self, forKeyPath:  #keyPath(myobjectinstance.downloadInProgress), options: [.old,.new], context: nil)

提示:以后尽量避免使用 KVO,因为它在 swift 中并不常见。

关于swift - 尝试删除 KVO 观察器时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43690768/

相关文章:

swift - 如何使用 swift 在 iOS 8 中插入图像 Inline UILabel

ios - 控制嵌套的 for 循环 Swift 3

xcode - Interface Builder 文件中的未知类 - Xcode 8 Swift 3

ios - 将普通搜索栏更改为下图,如搜索栏

ios - 重复目标无法找到 Storyboard 中引用的类 - 原始目标可以。

ios - persistenceEnabled 在模拟器中工作,但在设备上引发 NSInternalInconsistencyException

swift - 将旧的 KVO 转换为 Swift 4

objective-c - cocoa - -removeObserver :forKeyPath: and -removeObserver:forKeyPath:context:? 之间的细微差别

objective-c - 如何观察对象实例的创建/销毁?

swift - 列出您附近的所有信标