アプリの設定などを保存させたいときなどによく使うNSUserDefaults。
NSUserDefaultsを使う際の注意点を何点かメモっておきます。
(1) 値の即時反映
単に単純な話で、値を即時反映させたい場合は"synchronize"を使いましょうということ。
例えば、設定画面とかでSliderの変化に応じて値を保存したい場合、"synchronize"を使って即時反映させないと値の保存が遅れてしまいます。
なので、自動的な保存を待てない場合は以下のように"synchronize"を使います。
サンプルコード
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setFloat:value forKey:"ShowValue"];
BOOL successful = [ud synchronize];
参考資料
(2) immutable/mutable
NSUserDefaultsはimmutableな値を返します。
Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value
なので、以下のようにNSUserDefaultsを使って保存していた値を取り出して変更を加えて、再度保存しようとしたとするとエラーになります。
サンプルコード
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *userInfo = [ud valueForKey:@"USER_INFO"];
[userInfo setObject:@"SAMPLE" forKey:@"A"];
[ud setValue:userInfo forKey:@"USER_INFO"];
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
なので、以下のようにmutableCopyで作り直せば解決。
サンプルコード
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *userInfo = [[ud valueForKey:@"USER_INFO"] mutableCopy];
[userInfo setObject:@"SAMPLE" forKey:@"A"];
[ud setValue:userInfo forKey:@"USER_INFO"];