9

このコードは、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"]);
}

しかし、どうすれば変更されたキーの名前を取得できますか?

4

5 に答える 5

32

他の人が述べたように、NSUserDefaultsDidChange通知から変更されたキーに関する情報を取得する方法はありません。ただし、特定のプロパティについて具体的に通知する必要がある場合は、NSUserDefaultsでも機能するKey Value Observing(KVO)があるため、コンテンツを複製して自分で確認する必要はありません。

まず、NotificationCenterを使用する代わりにKVOに登録します。

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

オブザベーションを削除することを忘れないでください(例:viewDidUnloadまたはdealloc)

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

最後に、このメソッドを実装してKVO通知を受信します

-(void)observeValueForKeyPath:(NSString *)keyPath 
                 ofObject:(id)object
                   change:(NSDictionary *)change
                  context:(void *)context 
{
    NSLog(@"KVO: %@ changed property %@ to value %@", object, keyPath, change);
}
于 2012-06-08T13:54:45.033 に答える
2

通知のディクショナリにはデータが提供されていないため、他の場所に保存されているデータの別のコピーを保持して2つのディクショナリで差分を実行するuserInfo場合を除いて、運が悪いように見えます。NSUserDefaults

于 2012-06-03T16:11:41.993 に答える
1

カスタム通知を使用して、正確に何が起こったかを判断します。例:

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

userDefaultsのオプションでない場合は、NSUserDefaultsDidChangeNotification通知を受け取るたびにすべてのユーザーデフォルトを読み取り、以前のデフォルトと比較してください。

于 2012-06-06T05:31:22.653 に答える
1

追加するだけ[[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil];

appDidBecomeActiveメソッドに追加 してから追加します

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

あなたにapplicationDidEnterBackground

次に、フォアグラウンドで上記のようにKVOオブザーバーを使用します

于 2012-09-26T19:05:53.433 に答える
-1

asdictionaryRepresentationのコピー全体を取得するために使用できます。次に、以前の値と新しい値を比較します。NSUserDefaultsNSDictionary

NSUserDefaultsはKVOに準拠していないため、一部のKVO通知が発生する可能性があるという事実に依存するべきではなく、明らかに変更される可能性があります。

例えば:

- (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;
}
于 2015-11-30T10:08:47.110 に答える