Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSUserDefaults synchronize not saving on

I have a bug submitted by a tester that if he performs an action and then reboots his phone (by pressing the home and Sleep/Wake button down for a few seconds) the app is not persisting state.

I have been able to reproduce this issue. [NSUserDefaults synchronize] is getting called but when I restart the app after the reboot, the value inside NSUserDefaults was not saved.

Does anybody know if synchronize stores to a buffer which is later saved to disk? If so, how do I flush the buffer (I thought synchronize was the same as a flush, but apparently not.)

(edit) In other words:

assert([[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == NO);
[[NSUserDefaults standardUserDefaults] setBool: YES forKey: MY_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];

leave the app in the foreground and reboot the device after the above is called, then start the device back up and re-run the app. The assert should fire the second time around, but sometimes it doesn't.

To be very specific... I created a single view application and put the following code in the viewDidLoad

#define MY_KEY @"MY_KEY"

- (void)viewDidLoad
{
    [super viewDidLoad];
    BOOL key = [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY];
    NSLog(@"[[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == %@", key ? @"YES" : @"NO");
    [[NSUserDefaults standardUserDefaults] setBool: !key forKey: MY_KEY];
    [[NSUserDefaults standardUserDefaults] synchronize];
    NSLog(@"reboot now.");
}

Here is the output of three runs of the app:

2013-05-31 12:17:44.127 syncTest[162:907] [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == YES
2013-05-31 12:17:44.133 syncTest[162:907] reboot now.
2013-05-31 12:18:49.771 syncTest[128:907] [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == NO
2013-05-31 12:18:49.778 syncTest[128:907] reboot now.
2013-05-31 12:19:41.388 syncTest[124:907] [[NSUserDefaults standardUserDefaults] boolForKey: MY_KEY] == NO
2013-05-31 12:19:41.397 syncTest[124:907] reboot now.

Note that the output was "YES, NO, NO" but it should have been "YES, NO, YES"

like image 321
Daniel T. Avatar asked May 31 '13 15:05

Daniel T.


2 Answers

i had gone through the same problem and i identify that i had two reference of [NSUserDefaults standardUserDefaults] object on different classes because nsdefault is a singleton class soo the one called it earlier will have it if u might had already reference of [NSUserDefaults standardUserDefaults] try to finish it from the first reference and let the instance to be free from there and then call the instance at your other class and synchronize hopefully will be done

like image 78
Khurram Iqbal Avatar answered Sep 24 '22 21:09

Khurram Iqbal


In my case, some values I wrote to the NSUserDefaults did persist and some did not. After lots of searching, I noticed the the key-value pair that did not save had a key that was capipatilized, i.e. TheKey v.s theKey. When I changed my key to a camel-cased key (theKey instead of TheKey), the value did persist thru app quit and re-launch. It seems very weird to me why that would be, but it worked in my case.

like image 29
ndnguru Avatar answered Sep 24 '22 21:09

ndnguru