tags:

views:

25

answers:

2

Hi, i got a problem in [NSUserDefaults standardUserDefaults] in iOS4.0.

I saved some states by using [[NSUserDefaults standardUserDefaults] setObject:self.listData forKey:@"listData"]; in applicationDidEnterBackground: and applicationWillTerminate: methods. And i retrieved the data by using NSMutableArray *listData = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"listData"]]; in the viewDidLoad method.

I'm using sdk4.1 and simulator to test. The problem is: it does call the save method when my app enter the background. Since i want to know whether it's really been saved, so i double click the home button to call the multitask stack and hold the home button, then use the minus icon to kill my app in the background. Then i enter the app again, but the data didn't actually be saved.

Then i select the property Application does not run in background in the info.plist to see if it works in iOS3.0. And when i hit home button, it called the save method, then i enter the app, the data has been saved successfully.

So i'm wondering how the [NSUserDefaults standardUserDefaults] works in iOS4.0? How could i possibly save some data by using it in iOS4.0? Many thx!

+2  A: 

don't do that. I mean don't save prefs just before going to the bg as it does nothing. In fact you should read the specs. nsuserdefaults save you preferences in two different cases:

  1. every certain (not known?) amount of time
  2. when you call [NSUserDefaults synchronize]

If you save your prefs on your way to the bg, none of the above applies and so the prefs don't get saved.

gurghet
+1  A: 

To be more specific - [NSUserDefaults standardUserDefaults] is a pointer to a copy of the defaults file that is on the flash memory, not the defaults file itself. When you make changes, you are modifying this temporary copy only. It only gets written to flash memory when [NSUserDefaults synchronize] gets called. You should call this when your program exits.

In reality your program probably works fine. The real issue is that killing the app from the multitasking bar does not call all the app exit functions, its just killing the process, much like Force Quit in OSX (probably exactly like a Force Quit actually).

Your app works without multitasking because the default gets written in applicationWillTerminate and then [NSUserDefaults synchronize] is getting called for you in the normal exit process.

If you want your preferences to survive a user initiated force quit, you should write your defaults when you change them, and put a synchronize call into the applicationDidEnterBackground

fogelbaby
Yeah the correct pattern should be so "save" your prefs as they got changed, not at an arbitrary time.
gurghet
Well, I tried to put the synchronize in the applicationDidEnterBackground, and it works. But maybe i should save it when i change it.
JohnnySun
As for the [NSUserDefaults standardUserDefaults] is a pointer, that makes sense, because when i do something like NSUserDefaults *pref = [NSUserDefaults standardUserDefaults]. And then do the save stuff. Then i go to another class do NSUserDefaults *pref = [NSUserDefaults standardUserDefaults]. and it seems assign to the pref another address.
JohnnySun