NSUserDefaultsDidChangeNotification:叫什么名字的关键,是改变?(

2019-06-25 03:12发布

当UserDefaults一些值改变时,这个代码将调用方法“defaultsChanged”

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
           selector:@selector(defaultsChanged:)  
               name:NSUserDefaultsDidChangeNotification
             object:nil];

这段代码给我,改变了价值

- (void)defaultsChanged:(NSNotification *)notification {
    // Get the user defaults
    NSUserDefaults *defaults = (NSUserDefaults *)[notification object];

    // Do something with it
    NSLog(@"%@", [defaults objectForKey:@"nameOfThingIAmInterestedIn"]);
}

但我怎么能拿到钥匙,这改变了名字?

Answer 1:

正如其他人指出,有没有办法让有关从NSUserDefaultsDidChange通知改变的关键的信息。 但也没有必要复制任何内容,检查自己,因为有大价值观察(志愿),这还与NSUserDefaults的,如果您需要专门通知某一性质的:

首先,注册为国际志愿者组织,而不是使用通知中心:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults addObserver:self
           forKeyPath:@"nameOfThingIAmInterestedIn"
              options:NSKeyValueObservingOptionNew
              context:NULL];

不要忘记删除观察(如viewDidUnload或dealloc中)

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObserver:self forKeyPath:@"nameOfThingIAmInterestedIn"];

终于实现这个方法来接收志愿通知

-(void)observeValueForKeyPath:(NSString *)keyPath 
                 ofObject:(id)object
                   change:(NSDictionary *)change
                  context:(void *)context 
{
    NSLog(@"KVO: %@ changed property %@ to value %@", object, keyPath, change);
}


Answer 2:

没有通知的提供的数据userInfo字典,所以它看起来像你的运气,除非你想保留存储在数据的另一个副本NSUserDefaults其他地方以及两个库执行差异。



Answer 3:

使用自定义通知,以确定到底发生了什么,例如:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:self.event, @"eventObject", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"newEventCreated" object:nil userInfo:options];

如果不是与userDefaults一个选项,然后只需读取所有用户默认每次你得到你NSUserDefaultsDidChangeNotification通知,并与以前的康普艾它。



Answer 4:

只需添加[[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil];

appDidBecomeActive方法,然后添加

[ [NSNotificationCenter defaultCenter] addObserver:self selector:@selector(settingsChangedListener) name:NSUserDefaultsDidChangeNotification object:nil];

applicationDidEnterBackground

然后使用KVO观察者如上所示在前台时



Answer 5:

您可以使用dictionaryRepresentation获得的完整副本NSUserDefaults作为NSDictionary 。 然后,它是对先前的价值观和新的价值观的问题。

NSUserDefaults不符合志愿,事实上,它可能会触发一些志愿通知,不应被依赖并为被摄体明显改观。

例如:

- (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;
}


文章来源: NSUserDefaultsDidChangeNotification: What's the name Of the Key, that Changed?