是否可以使用KVO,不仅可以检测到值的变化,还可以检测是否再次设置相同的值?我目前只在值发生变化时收到通知(与之前设置的值不同)。我需要在每次设置值时接收通知(即使它与先前设置的相同)。我怎样才能做到这一点?
我的代码:
private func addObserver() {
defaults.addObserver(self, forKeyPath: DefaultsKeys.testKey._key, options: .new, context: nil)
}
public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard let value = change?[NSKeyValueChangeKey.newKey] as? Bool else { return }
statusCallback?(value)
}
private func removeObserver() {
defaults.removeObserver(self, forKeyPath: DefaultsKeys.testKey._key)
}
答案 0 :(得分:2)
UserDefaults
,并且它有一个特性可以防止这种情况发生(可能是一种优化,可以防止不必要的商店保存)。
您可以注册.didChangeNotification
,这似乎是调用值是否已更改:
NotificationCenter.default.addObserver(forName: UserDefaults.didChangeNotification, object: nil, queue: .main) { notification in
print("notification", notification)
}
答案 1 :(得分:0)
您可以通过以下方式实现此目的:
public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
let value = change?[.oldKey] as? Bool
guard value == nil || value != yourVariableToCheck else { return }
statusCallback?(value)
}
仅在您自己的变量上更改 yourVariableToCheck 。
答案 2 :(得分:0)
KVO机制非常简单 - 它在设置新值时不执行任何额外检查,仅在调用setter时触发。因此,如果该值与已经设置的值不同,则不可能区分。 这很好。首先,因为在实践中为变量赋予相同的值并不常见 其次,引入额外的检查将是消耗品,并且在大多数情况下是不需要的。如果检查存在,则会对性能产生负面影响。
话虽如此,就Swift而言,您可以考虑使用本机Swift属性观察器替换KVO机制(实质上是Objective-C遗留):willSet
和didSet
。这基本上与将两个选项:NSKeyValueObservingOptionNew
和NSKeyValueObservingOptionOld
(Swift中的.old
和.new
)传递给addObserver
方法的角色相同。一旦指定了这些标志,每当触发KVO机制时,您将在observeValue(...)
中收到两个值(旧的和新的),从中可以决定如何处理这两个值。但是,当willSet
几乎完全相同并且更加稳定时,为什么你需要这样的复杂性:
var myVariable : String! {
willSet {
print("Old value is: \(myVariable)")
print("New value is: \(newValue)")
// Let's do something with our old value
}
didSet {
print("Just set the new value: \(newValue)")
// New value is set. Let's do some actions.
}
}
答案 3 :(得分:0)
如果要跟踪NSUserDefaults
中的每个设置,即使新值与以前的值相同,也请用NSDictionary
包裹该值,然后将{{1 }}值,每次调用新的NSUUID
时都会生成。
之前({setValue
并未在每个observeValueForKeyPath
上调用):
setValue
(每[self.mySharedDefaults setValue: @"CHECKING" forKey:@"appStatusOUT"];
被调用observeValueForKeyPath
之后):
setValue