views:

43

answers:

1

I am having problems with the context in Core Data not being able to save.

I get random crashes when I try to call [context save:]. Sometimes it works, sometimes it doesn't and crashes the app. Here is my delete code. I have been able to reduce the number of crashes by checking if [context respondsToSelector] save. The strange this is even when it fails (respondsToSelector fails), and I didn't call save, it still gets deleted!? But also when the respondsToSelector succeeds, and I attempt to call save, it still crashes sometimes. So the code is a little more stable with the test, but I think there is something wrong with Core Data and the save method. It has been very hard to track down the problem because it really does seem random.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the managed object.
        NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
        Accidents* accidentDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
        [context deleteObject:accidentDelete];

        // Causing crash...
        NSError *error = nil;

        if ([context respondsToSelector:@selector(save:)])
            if (![context save:&error]) {
                // Update to handle the error appropriately.
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                exit(-1);  // Fail
            }
        else
            NSLog(@"Error! Context does not respond to save!");   
    }
} 
+1  A: 

I'm assuming that crash means -- EXC_BAD_ACCESS. If not, please post the exception you are getting and the stack trace.

EXC_BAD_ACCESS happens because you are accessing bad memory. Usually this is because you are accessing freed memory. The easiest way to track that down is to turn on zombies -- this makes all deallocs do nothing, but when you access an object that has had dealloc called on it, it will complain in the console, with the exact point that you are access a freed object.

I explain a lot more about EXC_BAD_ACCESS here, with some troubleshooting instructions (and instructions for turning on zombies)

http://www.loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

Go to Project->Edit Active Executable, go to the Arguments tab and in the environment variables section, add

NSAutoreleaseFreedObjectCheckEnabled 
NSZombieEnabled    
NSDebugEnabled 

And set each to YES. You can leave them there unchecked, but if you check them, then your application will now do some extra checking on autorelease and release and give you a good stack trace when you have done it wrong. A common problem is to think you need to call release when the object is already set to autorelease (see yesterday's post on what the rules are for that).

Lou Franco
I wasn't getting a bad access, but a SIG-BIT instead. But your hint of adding the environment variables is what I needed to figure out why it was crashing. For some reason, I was releasing a date object too soon and then accessing it. When Core Data went to save it, it wasn't there anymore and crashed. I solved this by making a date object an auto release object [NSDate date]. It seems to work now. After enabling the environ variable,I got a console message saying I was sending a message to a date object that was released, which was the hint I needed.
Leon Fu