xcode NSUserDefaultsDidChangeNotification:更改的密钥的名称是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10871860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSUserDefaultsDidChangeNotification: What's the name Of the Key, that Changed?
提问by smudo78
This code will call the method "defaultsChanged", when some value in UserDefaults changed
当 UserDefaults 中的某些值发生更改时,此代码将调用方法“defaultsChanged”
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
selector:@selector(defaultsChanged:)
name:NSUserDefaultsDidChangeNotification
object:nil];
This Code will give me the VALUE that changed
这段代码会给我改变的 VALUE
- (void)defaultsChanged:(NSNotification *)notification {
// Get the user defaults
NSUserDefaults *defaults = (NSUserDefaults *)[notification object];
// Do something with it
NSLog(@"%@", [defaults objectForKey:@"nameOfThingIAmInterestedIn"]);
}
but how can I get the NAME of the key, that changed??
但是我怎样才能得到改变的密钥的名称?
回答by auco
As others stated, there is no way to get the info about the changed key from the NSUserDefaultsDidChange Notification. But there is no need to duplicate any content and check for yourself, because there is Key Value Observing (KVO)which also works with the NSUserDefaults, if you need to specificallybe notified of a certain property:
正如其他人所说,无法从 NSUserDefaultsDidChange 通知中获取有关已更改密钥的信息。但是没有必要复制任何内容并自己检查,因为有键值观察 (KVO)也可以与 NSUserDefaults 一起使用,如果您需要特别通知某个属性:
First, register for KVO instead of using the NotificationCenter:
首先,注册 KVO 而不是使用 NotificationCenter:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults addObserver:self
forKeyPath:@"nameOfThingIAmInterestedIn"
options:NSKeyValueObservingOptionNew
context:NULL];
don't forget to remove the observation (e.g. in viewDidUnload or dealloc)
不要忘记删除观察(例如在 viewDidUnload 或 dealloc 中)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObserver:self forKeyPath:@"nameOfThingIAmInterestedIn"];
and finally implement this method to receive KVO notifications
最后实现这个方法来接收 KVO 通知
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSLog(@"KVO: %@ changed property %@ to value %@", object, keyPath, change);
}
回答by Jacob Relkin
There is no data provided in the notification's userInfo
dictionary, so it looks like you're out of luck unless you want to keep another copy of the data stored in NSUserDefaults
elsewhere and perform a diff on the two dictionaries.
通知的userInfo
字典中没有提供数据,所以看起来你运气不好,除非你想在NSUserDefaults
别处保存另一个数据副本并对两个字典执行差异。
回答by Maxim Mikheev
Use custom notifications to determine what exactly happened, e.g.:
使用自定义通知来确定究竟发生了什么,例如:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:self.event, @"eventObject", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"newEventCreated" object:nil userInfo:options];
If it is not an option with userDefaults, then just read all user defaults everytime you get your NSUserDefaultsDidChangeNotification
notification and compair it with previous ones.
如果它不是 userDefaults 的一个选项,那么每次收到NSUserDefaultsDidChangeNotification
通知时只需读取所有用户默认值并将其与以前的进行比较。
回答by j2emanue
just add [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil];
只需添加 [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil];
to your appDidBecomeActive
method and then add
到您的appDidBecomeActive
方法,然后添加
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(settingsChangedListener) name:NSUserDefaultsDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(settingsChangedListener) name:NSUserDefaultsDidChangeNotification object:nil];
to your applicationDidEnterBackground
给你的 applicationDidEnterBackground
then use KVO observer as shown above when in the foreground
然后在前台使用 KVO 观察器,如上所示
回答by Ben Sinclair
You can use dictionaryRepresentation
to obtain the entire copy of NSUserDefaults
as NSDictionary
. Then it's a matter of comparing previous values and new values.
您可以使用dictionaryRepresentation
获取NSUserDefaults
as的整个副本NSDictionary
。然后是比较以前的值和新值的问题。
NSUserDefaults
is not KVO compliant, the fact that it may fire some KVO notifications should not be relied upon and is a subject to change apparently.
NSUserDefaults
不符合 KVO,它可能会触发一些 KVO 通知的事实不应被依赖,并且显然可能会发生变化。
For example:
例如:
- (void)setupUserDefaults {
self.userDefaults = [NSUserDefaults standardUserDefaults];
[self.userDefaults registerDefaults:@{ /* ... */ }];
self.userDefaultsDictionaryRepresentation = [self.userDefaults dictionaryRepresentation];
[notificationCenter addObserver:self
selector:@selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:self.userDefaults];
}
- (void)userDefaultsDidChange:(NSNotification *)note {
NSDictionary *oldValues = self.userDefaultsDictionaryRepresentation;
NSDictionary *newValues = [self.userDefaults dictionaryRepresentation];
NSArray *allKeys = @[ /* list keys that you use */ ];
for(NSString *key in allKeys) {
id oldValue = oldValues[key];
id newValue = newValues[key];
if(![oldValue isEqual:newValue]) {
[self notifyObserversForKeyChange:key oldValue:oldValue newValue:newValue];
}
}
self.userDefaultsDictionaryRepresentation = newValues;
}