键值观察异常行为

时间:2019-01-29 13:19:00

标签: swift macos key-value-observing kvc

也许这个问题比我看上去的要笼统,但是我想确保在出现某些问题的情况下,能显示出我的完整背景。

  1. 我写了一个具有KVC兼容属性和两个方法的单例类:
class Singleton: NSObject {
    static let sharedInstance = Singleton()

    @objc dynamic var aProperty = false

    func updateDoesntWork() {
        aProperty = !aProperty
    }

    func updateDoesWork() {
        Singleton.sharedInstance.aProperty = !aProperty
    }
}
  1. 我在应用程序委托的设置代码中添加了属性的观察者:
Singleton.sharedInstance.addObserver(self, forKeyPath: #keyPath(Singleton.aProperty), options: [.new], context: nil)
  1. 我重写了我的应用程序委托的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(),那么一切都会按我的预期进行-当然,该属性也已更改,但最重要的是,这次通知了观察者更改(打印日志条目) )。

对于我来说,为了使KVO正常工作,我需要完整的Singleton.sharedInstance.aProperty而不是aProperty毫无意义。我想念什么?

1 个答案:

答案 0 :(得分:0)

我认为您在将“ var”用于单例时遇到麻烦。您可以考虑使用以下代码段创建一个单例并初始化一些值,包括该单例专用的观察值:

class Singleton: NSObject {
    static private var sharedInstanceObserver : NSKeyValueObservation!

    static let sharedInstance: Singleton = {
        let sInstance = Singleton()
        sharedInstanceObserver = sInstance.observe(\Singleton.aProperty, options: .new) { st, value in
            print(st, value)
        }
        return sInstance
    }()

    @objc dynamic var aProperty = false

    func updateDoesntWork() {
        aProperty = !aProperty
    }

    func updateDoesWork() {
        Singleton.sharedInstance.aProperty = !aProperty
    }
}