views:

252

answers:

2

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSobject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). After alot of searching and trying i got it to correctly save (and load) this data through the use of NScoding and NSKeydArchiver.

Every screen in my app basically is a view of a little piece of information from this datamodel. Since one can change data in some of these views the data needs to be saved and loaded between screen transitions.

My screen view chain is this: root -> view 1 -> subview 1

Here comes the odd part:

In subview 1 i load the dataobject from the NSUserdefaults and present the information (this works), then the user can edit the data (in this case a NSString describing a company name) When the user presses the back button in the topbar to return to "view 1" it triggers a save (this also works).

Back at "View 1" a "viewwillappear" event is triggered. In this trigger i reload the saved data from "subview 1" and redraw my screen (a uitableviewcontroller). For some reason, after the load the changes made in the previous screen are not reflected! The loaded object still contains the same values as if the save hadn't happened!

After some logging it seems that even though i CALL the save before the LOAD, it apparently gets executed later. So the confirmed (by debug breakpoints) actions are -> LOAD -> SAVE -> LOAD. But according to the logfunction (i log each save and load call) it ends up as -> LOAD -> LOAD -> SAVE.

Can anyone help me with this? - I have no idea what i'm doing wrong here.

This code is called from an object i create wherever i need it (in time it needs to be replaced with a singleton) and i access the saved and loaded data by MyDataStoreObject.currentData

- (void) saveCurrentData {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject: currentData];
    [defaults removeObjectForKey:@"MYAPP_CURRENTDATA"];
    [defaults setObject:data forKey:@"MYAPP_CURRENTDATA"];

    [defaults synchronize];
}

- (void) loadCurrentData {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSData *data = [defaults objectForKey:@"MYAPP_CURRENTDATA"];

    if (data == nil)
    {
     currentData = nil;
     NSLog(@"NO DATA TO RETRIEVE FROM USERDEFAULTS");
    }
    else
    {
     currentData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    }
}
+2  A: 

Call synchronize on your NSUserdefaults instance after you save, to ensure all the contents you save are written down and preserved immediately.

Edit:

In

When the user presses the back button in the topbar to return to "view 1" it triggers a save (this also works).

How did you do that? Show us the code that catches the back button being touched, I'm curious if it performs the save every time.

luvieere
I added a code snippet of how i load and save my data. The loading and saving do work, but for some reason its not guaranteed to work in the order i am calling the functions?
Edwin Bos
A: 

Well it seems my load and save code are working properly. Apparently it's possible for a view to fire an event, after the next view has it's viewdidload event already fired.

I am now using the viewWillDisapear function to save, and the viewWillAppear function to load.

phew!

Edwin Bos
This should have been an update to the original question, or a comment. −1
coneybeare