class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("in viewDidLoad");
// addObserver keyPath
UserDefaults.standard.addObserver(self, forKeyPath: "testKey", options: .new, context: nil);
print("out viewDidLoad");
}
deinit {
// removeObserver keyPath
UserDefaults.standard.removeObserver(self, forKeyPath: "testKey");
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("in observeValue keyPath: \(keyPath) value: \(UserDefaults.standard.integer(forKey: "testKey"))");
// 1. If I execute the func click () method, it will be executed two times
// 2. If App originally existed "testKey", then func observeValue () will be executed after the viewDidLoad is finished.
}
@IBAction func click(_ sender: NSButton) {
UserDefaults.standard.set(arc4random(), forKey: "testKey");
}
}
The above code is all of my test code. I used KVO in my own project, but found repeated execution.
// 1. If I execute the func click () method, it will be executed two times
// 2. If App originally existed "testKey", then func observeValue () will be executed after the viewDidLoad is finished.
This is not what I understand about KVO. My idea is that after addObserver, my observeValue will be called if my key is changed. But it didn't turn out that way. I tried to find the answer to the forum, and I didn't find the answer. I just found a similar question.
If I press Button in my view, then the final result will be..:
in viewDidLoad
out viewDidLoad
in observeValue keyPath: Optional("testKey") value: 4112410111
in observeValue keyPath: Optional("testKey") value: 3712484288
in observeValue keyPath: Optional("testKey") value: 3712484288
macos: 10.12.6 (16G29) xcode: 9 beta6、xcode 8.3.3
If you have the same problem, please tell more people to help us solve it. Thank you
I have sent the same question to the official, and if there is a solution, I will return it here.