【发布时间】:2019-01-29 13:18:59
【问题描述】:
也许这个问题比我想象的更笼统,但我想确保我展示了我的完整背景,以防出现这个问题的原因。
- 我编写了一个带有符合 KVC 的属性和两个方法的单例类:
class Singleton: NSObject {
static let sharedInstance = Singleton()
@objc dynamic var aProperty = false
func updateDoesntWork() {
aProperty = !aProperty
}
func updateDoesWork() {
Singleton.sharedInstance.aProperty = !aProperty
}
}
- 我在我的应用委托的设置代码中为该属性添加了一个观察者:
Singleton.sharedInstance.addObserver(self, forKeyPath: #keyPath(Singleton.aProperty), options: [.new], context: nil)
- 我覆盖了我的应用代理的
observeValue()方法:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
NSLog("observeValue(forKeyPath: \(String(describing:keyPath)), of: \(String(describing:object)), change: \(String(describing:change)), context:\(String(describing:context)))")
}
现在,如果我打电话给Singleton.sharedInstance.updateDoesntWork(),我不会得到aProperty 中更改的日志条目。属性发生了变化(我在调试器中验证了这一点),只是没有发送通知。
然而,如果我调用Singleton.sharedInstance.updateDoesWork(),一切都会按我的预期运行——当然,属性也发生了变化,但最重要的是,这次通知观察者发生了变化(打印了日志条目)。
对我来说,我应该需要完整的 Singleton.sharedInstance.aProperty 而不仅仅是 aProperty 才能使 KVO 工作,这对我来说毫无意义。我错过了什么?
【问题讨论】:
-
我无法重现这个。两种方法都可以为我记录,没有麻烦。我会尝试将其精确到您在此处描述的内容,并在一个小型测试应用程序中进行尝试。例如,这是我使用的游乐场(我也在 iOS 应用中使用 app 委托进行了测试):gist.github.com/rnapier/4500b87cd3a253020be56e8bd03f54d3 最可能的原因是您没有观察到您认为自己是的对象,或者您正在调用
updateDoesntWork在你观察之前。 -
这里也一样。无法重现(在命令行应用程序中)。
-
请注意,如果不将
Singleton的初始化程序设为私有,您实际上并不能保证只会创建shared实例,您只能保证您始终可以访问该实例具体实例。此外,你为什么不使用 Swift 4 的 KVO 而不是旧的 Obj-C 呢?见Key-Value Observing in Swift -
@swineone: ...这意味着您在上面发布的不是显示问题行为的真实代码。
-
@MartinR 确实如此,对此我深表歉意。如果我真的尝试创建一个真正的 MCVE,我会发现我在我的应用程序委托中写
var singleton = Singleton()的部分,而不是正确的var singleton = Singleton.sharedInstance,我什至不会问这个问题。我的错。
标签: swift macos key-value-observing kvc