views:

64

answers:

1

Okay, of course it is possible, that's no issue. In my code I have multiple objects that I work with, and they need to be data persistent. To do that I've used object encoding and storing them in a data file. Such as:

-(NSString *)dataFilePath
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:kFilename];
}

And then further along in another section of code:

NSMutableData *data = [[NSMutableData alloc] init];
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        NSLog(@"Test 4");
        [archiver encodeObject:playerTwo forKey:@"PlayerTwoObject"];
        [archiver encodeObject:singlePlayer forKey:@"SinglePlayer"];
        [archiver encodeObject:playerOne forKey:@"PlayerOneObject"];
        [archiver encodeObject:settings forKey:@"Settings"];


        [archiver finishEncoding];
        [data writeToFile:[self dataFilePath] atomically:YES];
        [singlePlayer release];
        [playerOne release];
        [playerTwo release];
        [settings release]; 

And that saves the objects. I know it works, because I can take them out with this code:

unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:[[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]]];
    SettingsObject *settings = [unarchiver decodeObjectForKey:@"Settings"];
    Player *test = [unarchiver decodeObjectForKey:@"PlayerOneObject"];
    NSLog(@"Power On Settings Test: %d,%d", [settings playerOneStartingLife], [settings singlePlayerStartingLife]);
    NSLog(@"Power On Player Test: %@,%d", [test name], [test life]);

Cool! So now I can store my objects, and read them out. So this is where the issue comes in. In a different class I take out one of the objects I'm storing and work with it. Not all of them, I only read out one. And then I save it again after I change the settings. But I only save it:

NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:singlePlayer forKey:@"SinglePlayer"];
    [archiver finishEncoding];
    [data writeToFile:[self dataFilePath] atomically:YES];
    [singlePlayer release];

After I have done that, all the rest of the objects I have stored are removed. Now I'm confused, because I thought I was only editing the one key "SinglePlayer", but apparently that somehow removes the rest of them? Is that supossed to happen? I have had some issues with releasing the archiver, would that affect it at all... I don't think it would. Does anyone have some insight on this, because I don't want to have to take all of the objects out and re-encode them if I only want to edit one of them...

Thanks for your help!

+2  A: 

You create a new archiver, with an emtpy data object. You write the SinglePlayer object in the data, but you do not store the rest of the data in the same, newly created archive.

To do so, unarchive the whole previously stored archive, then adjust the SinglePlayer object and archive and save it again.

JoostK
Ugggh, that seems terrible inefficient. Is there a better way of doing this? Perhaps I should use SQLite instead?
Wayfarer
Better to switch to Core Data then. Core Data is backed by SQLite but can be used far more easily when dealing with objects and relationships.
JoostK
Whether to use Core Data or SQLite depends entirely on what you're trying to do and is currently the subject of much debate. http://inessential.com/2010/02/26/on_switching_away_from_core_data Also, Core Data can use SQLite as a store type, but it's no more "backed" by SQLite than any other store type (such as XML, binary, or some custom store type).
Joshua Nozzi
Yes, that's true. But when not using SQLite as the Core Data storage type, there would be the same overhead in loading all of the data, then adjusting just one property and then saving all the data again.
JoostK