0

Consider the following example:

NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
[def synchronize];

if([def objectForKey:@"Test_Value_1"] != nil){
  [def removeObjectForKey:@"Test_Value_1"];
  [def setBool:YES forKey:@"Test_Value_2"];
}

if (![def boolForKey:@"Test_Value_2"]){
...
}

Is is possible that the Test_Value_1 gets removed but the Test_Value_2 is not set? I'm not synchronizing after i change these values. My understanding is that the changes will kept in memory and then synchronized at some time later. So i should be save. The only possible way would be if after [def removeObjectForKey:@"Test_Value_1"]; the app would crash but i think thats highly unlikely.

Apurv
  • 17,116
  • 8
  • 51
  • 67
kukudas
  • 4,834
  • 5
  • 44
  • 65
  • 1
    Synchronization is unnecessary in most cases. Calls to mutate NSUserDefaults propagate effectively immediately, so why should you care when and if they are persisted to disk? – CodaFi Apr 02 '14 at 06:03
  • In the second statement i'm removing some stuff. I got feedback of some strange behavior and identified this place as a potential trigger for it. However i cannot reproduce it. – kukudas Apr 02 '14 at 06:25
  • If you can manage to reproduce it, then it's clearly a bug to be worked out on Apple's end. Otherwise, you're fishing for implementation details, which won't help you at all. – CodaFi Apr 02 '14 at 06:26

3 Answers3

2

"The sncronize method writes any modifications to the persistent domains to disk and updates all unmodified persistent domains to what is on disk."

"This method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit)"

and in your case the app will not crash as you first check weather there is an object for the key "Test_Value_1" in user defaults, so if the key is removed then it will not execute the code in if condition.

Harish Suthar
  • 711
  • 1
  • 4
  • 14
1

From Apple Docs:

At runtime, you use an NSUserDefaults object to read the defaults that your application uses from a user’s defaults database. NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value. The synchronize method, which is automatically invoked at periodic intervals, keeps the in-memory cache in sync with a user’s defaults database.

So if your application crashes in between the time interval of storing the value in cache and before they get store in DB, your application may not have updated value.

Apurv
  • 17,116
  • 8
  • 51
  • 67
0

synchronize is used to write user defaults immediately to disk.

before ios7 iOS already does it at appropriate moments, but in ios7 its not the case so you have to explicitly synchronize user defaults.

For further details please check Apple doc

and enter link description here

Community
  • 1
  • 1
Viper
  • 1,408
  • 9
  • 13
  • That's intresting. Is there any official documentation for the changed behavior under iOS7 ? – kukudas Apr 02 '14 at 06:26
  • NSUserDefaults' documentation is notoriously shoddy. No guarantees are made about when writes are made to the disk, even if you call -synchronize. iOS 7 may have tweaked the implementation of NSUserDefaults, but it certainly doesn't imply that every iOS before it required calls to -synchronize explicitly. – CodaFi Apr 02 '14 at 06:29