Core Data database doesn't save
I'm trying to implement the Paparazzi 2 assignment from the Stanford CS193 course and I'm running into a problem. My one call to save the database is when the app exits (I'm borrowing heavily from Mike Postel's version to check my code):
- (void)applicationWillTerminate:(UIApplication *)application {
if (flickrContext != nil) {
if ([flickrContext hasChanges] == YES) {
NSError *error = nil;
BOOL isSaved = [flickrContext save:&error];
NSLog(@"isSaved? %@", (isSaved ? @"YES" :@"NO") );
// Replace this implementation with code to handle the error appropriately.
if(isSaved == NO){
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
}
Unfortunately, this doesn't seem to be doing the job. I'm getting the occasional EXEC_BAD_ACCESS 开发者_如何学JAVAcall that might be related to this, but the database never saves. I've inserted the save into other pieces and it works fine there, just not in this routine. I'm not releasing any of the managed objects in my views, just the managed object context (flickrContext, or whatever I'm calling it in a view).
Any ideas?
Are you sure that applicationWillTerminate:
is even being called?
With iOS4 and background process support, the usual application lifecycle is now:
running -> background -> background suspended -> exit
You get an applicationDidEnterBackground:
call when transitioning into the background state, but no further notification when the background process suspends or exits.
So, you really need to save state in applicationDidEnterBackground:
for iOS4, as well as in applicationWillTerminate:
for older versions
flickrContext is your managedObjectContext? I'm betting it is nil or otherwise hosed when you hit this method. You say you are releasing it in a view - surely you should be creating just one, having it owned by the application delegate, and release it only in app delegate's dealloc
?
(And when you need to use it -
NSManagedObjectContext* moc = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
)
Regarding your EXEC_BAD_ACCESS - what happens with NSZombieEnabled = YES? What does the static analyzer say?
Good call. I actually solved this one the old fashioned (brute force) way. It turns out that applicationWillTerminate wasn't being called, but it wasn't obvious. The routine to create the database that I had borrowed from the web was explicitly releasing an NSArray that I'm pretty sure was autoreleased. It essentially turned the program into a time bomb. Although I still haven't figured out why it lasted as long as it did and just didn't manifest until I tried to exit.
I'm still learning XCode and CocoaTouch. I know about NSZombieEnabled but I haven't figured out how to use it correctly yet. I'm still in the ham-fisted monkey stage. Thanks for the tips, though. They were helpful.
精彩评论