views:

95

answers:

3

I added a new entity to my model and it loads fine but no changes made in memory get persisted to disk. My values set on the car object work fine in memory but aren't getting persisted to disk on hitting the home button (in simulator). I am using almost exactly the same code on another entity in my application and its values persist to disk fine (core data -> sqlite3); Does anyone have a clue what I'm overlooking here? Car is the managed object, cars in an NSMutableArray of car objects and Car is the entity and Visible is the attribute on the entity which I am trying to set. Thanks for you assistance. Scott

- (void)viewDidLoad {
   myAppDelegate* appDelegate = (myAppDelegate*)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext* managedObjectContex = appDelegate.managedObjectContext;
    NSFetchRequest* request = [[NSFetchRequest alloc] init];
    NSEntityDescription* entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:managedObjectContex];
    [request setEntity:entity];

    NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Name" ascending:YES];
    NSArray* sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [request setSortDescriptors:sortDescriptors];

    [sortDescriptors release];
    [sortDescriptor release];

    NSError* error = nil;
    cars = [[managedObjectContex executeFetchRequest:request error:&error] mutableCopy];

    if (cars == nil) {
        NSLog(@"Can't load the Cars data! Error: %@, %@", error, [error userInfo]);
    }


    [request release];

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
    Car* car = [cars objectAtIndex:indexPath.row];

    if (car.Visible == [NSNumber numberWithBool:YES]) {
        car.Visible = [NSNumber numberWithBool:NO];
        [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
    }
    else {
        car.Visible = [NSNumber numberWithBool:YES];
        [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;

    }

    }

Here are my persistent store coordinator options:

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSDictionary* options =  [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES],
                    NSMigratePersistentStoresAutomaticallyOption, 
                         [NSNumber numberWithBool:YES], 
                         NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {

}    
+1  A: 

When you add a new entity to your application's managed object context, you have to use the managed object context's -save: method afterwards to save those changes.

I strongly suggest reading through Apple's Core Data Programming Guide to learn about Core Data objects and methods, and how entities are created, saved, deleted and modified.

Alex Reynolds
I tried putting a context save as you suggested after modifying an existing managedobject and I still get the same results.By "add a new entity" are you referring to adding a new nsmanagedobject to the context? I'm only using an preexisting instances returned with the FetchRequest and trying to modify that instance. My statement about the entity was referring to adding an entity to my model and instances of that entity can be read but not written even though I don't have that problem with other entities in my model.Does this make sense or did I misunderstand your suggestion?
scott
I misunderstood your question. Nonetheless, whenever you make a change to an entity, if you want those changes to persist you have to save the managed object context.
Alex Reynolds
scott
Thanks for you help. Definitely made me thing more about what was going on and helped me get to the bottom of the issue.
scott
A: 

I suspect Alex has the right answer but can you post the code that shows you creating a NSManagedObject?

Update

Then Alex is right, you are not saving the data. Since you say you added a save routine, share that code.

Marcus S. Zarra
Per my comment to Alex, I'm not creating new NSManagedObjects only trying to modify the ones returned in the fetch above. The modifications work in memory but do not persist.
scott
To be more clear, I am populating the storeUrl parameter to my persistantstorecoordinator instantiation with this code which points to a prepopulated db. [self createEditableCopyOfDatabaseIfNeeded]; NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Cars.sqlite"]];
scott
I put the save code in the new comment to alex. I believe its something else though as save is definitely getting called and the changes are definitely getting detected in that code. Its just not writing the complete set of values to the db.
scott
Thanks for your help! Posted the answer below but with the information I supplied the error wouldn't have been detected here.
scott
A: 

I was totally barking up the wrong tree on this one.

What helped me find the issue was turning on core data traces with this execution parameter: -com.apple.CoreData.SQLDebug 1

Turns out I had a logic problem in choosing how to display the Visible values (I hadn't posted the code for that) which was resulting in the bug. Core data was doing the right thing and only writing changes when the values differed but I was unable to tell because I was displaying the values incorrectly.

scott
you should flag this as the answer then to close out this question.
Marcus S. Zarra