Getting an NSInternalInconsistencyException Error! - iphone

I am getting the error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Exercise''
At the line: Exercise *exercise = (Exercise *)[NSEntityDescription insertNewObjectForEntityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
(You can see my data model here: How is This Data Model?).
Any ideas why?
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(exerciseChooser)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
//if (managedObjectContext == nil)
{
managedObjectContext = [(CurlAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSLog(#"After managedObjectContext: %#", managedObjectContext);
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[mutableFetchResults release];
[request release];
}
-(IBAction)exerciseChooser
{
RoutineExerciseChooserViewController *routineExerciseChooserViewController = [[[RoutineExerciseChooserViewController alloc] init] autorelease];
[self.navigationController pushViewController:routineExerciseChooserViewController animated:YES];
}
-(void)addExercise
{
Exercise *exercise = (Exercise *)[NSEntityDescription insertNewObjectForEntityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
exercise.name=#"Test";
NSError *error = nil;
if (![managedObjectContext save:&error])
{
// Handle the error.
}
NSLog(#"%#", error);
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSInteger lastSection = [self.tableView numberOfSections] -1;
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.tableView numberOfRowsInSection:lastSection]-1 inSection:lastSection] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

This error has only a few possible sources:
Typo in the Entity name.
Nil managed object context object.
Failure to add the model containing the entity to the persistent store the context uses.
Failure to add the correct persistent store to the context itself.
Please also refer to this previous question:
insertNewObjectForEntityForName:
UPDATE
Why is the if statement commented out?
if(managedObjectContext == nil)
I think it's required.
EDIT
-(void)addExercise
{
if(managedObjectContext!=nil)
{
Exercise *exercise = (Exercise *)[NSEntityDescription insertNewObjectForEntityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
exercise.name=#"Test";
NSError *error = nil;
if (![managedObjectContext save:&error])
{
// Handle the error.
}
NSLog(#"%#", error);
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSInteger lastSection = [self.tableView numberOfSections] -1;
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.tableView numberOfRowsInSection:lastSection]-1 inSection:lastSection] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}

Related

Table view and Predicates

I have a table view with 40 objects. I have to filter them by gender when Click in a UISegment (male, female and both). It seems to be working, but table view does not refresh. Please any help would be appreciatte.
-(void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"People";
[self loadall];
[[NSBundle mainBundle] loadNibNamed:#"FilterSortView" owner:self options:nil];
self.filterControl.selectedSegmentIndex = -1;
[self.filterControl addTarget:self action:#selector( changeSegge ) forControlEvents:UIControlEventValueChanged];
}
#
My second method to filter by gender
- (void)changeSegge
{
NSEntityDescription *personEntity = [NSEntityDescription entityForName:#"Person"
inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:personEntity];
NSError *error = nil;
self.people = [self.managedObjectContext executeFetchRequest:request error:&error];
if (error)
{
[NSException raise:NSInternalInconsistencyException format:#"Could not fetch Core Data records: %#",error];
}
if(filterControl.selectedSegmentIndex == 0){
NSPredicate *predicatem =[NSPredicate predicateWithFormat:#"gender == %#", #"m" ];
request.predicate=predicatem;
[self.tableView reloadData];
[request release];
NSLog(#"button 1");
}
Thanks a lot.
You forgot to fill people array after predicate set to fetch request.
Here is updated changeSegge method:
- (void)changeSegge
{
NSEntityDescription *personEntity = [NSEntityDescription entityForName:#"Person"
inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:personEntity];
NSError *error = nil;
self.people = [self.managedObjectContext executeFetchRequest:request error:&error];
if (error)
{
[NSException raise:NSInternalInconsistencyException format:#"Could not fetch Core Data >records: %#",error];
}
if(filterControl.selectedSegmentIndex == 0){
NSPredicate *predicatem =[NSPredicate predicateWithFormat:#"gender == %#", #"m" ];
request.predicate=predicatem;
self.people = [self.managedObjectContext executeFetchRequest:request error:&error];
[self.tableView reloadData];
[request release];
NSLog(#"button 1");
}

Core Data Crash during Save without error. Only one Context and only main thread

I'm simply trying to delete three nsmanagedobject from an entity, as i already do in other application,where all went ok. This time core data seems to crash during save, there's no error, i'm using the app delegate context in all the app, so i think that isn't a multiple context problem... I have tried a check with [NSThread isMainThread] , during the save i'm in the main thread, so isn't a threading problem... What's wrong in my code?
-(void)EraseStore{
if (contesto == nil) {
contesto = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSError *error=nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Store" inManagedObjectContext:contesto];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [contesto executeFetchRequest:fetchRequest error:&error];
NSString *Store1=[NSString stringWithFormat:#"%#",#"55"];
NSString *Store2=[NSString stringWithFormat:#"%#",#"63"];
NSString *Store3=[NSString stringWithFormat:#"%#",#"11"];
for (int i=0; i<[fetchedObjects count]; i++) {
NSString *StoreId=[NSString stringWithFormat:#"%#",[[fetchedObjects objectAtIndex:i]valueForKey:#"id"]];
if ([StoreId isEqualToString:Store1] || [StoreId isEqualToString:Store2]|| [StoreId isEqualToString:Store3]) {
[contesto deleteObject:[fetchedObjects objectAtIndex:i]];
}
}
NSError *error1 = nil;
BOOL success = [contesto save:&error1];
if (!success) {
NSLog(#"Unresolved error2 %#, %#", error1, [error1 userInfo]);
}
else{
NSLog(#"saved");
}
}
How I create my context:
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext_ != nil) {
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext_ = [[NSManagedObjectContext alloc] init];
[managedObjectContext_ setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext_;
}
The error message I am getting:
Unresolved error2 Error Domain=NSCocoaErrorDomain Code=133020 "The operation couldn’t be completed. (Cocoa error 133020.)" UserInfo=0x23cf00 {conflictList=( "NSMergeConflict (0x23cdc0) for NSManagedObject (0x234960) with objectID '0x2da8b0 ' with oldVersion = 1 and newVersion = 2 and old object snapshot =....
EDIT
In database structure i haven't set any relationship between tables.

Error when populating table view with coredata

I am working with coredata and successfully saved the data in data storage but when I try to output what I stored using table view ,I am not able to do it.
Here the user will enter and click save ..so when he goes back..I want the table to populated with what name he or she has entered.
So I wrote the below code for saving and find data:
- (void) saveData
{
coredata123AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
Contacts *newContact;
newContact = [NSEntityDescription
insertNewObjectForEntityForName:#"Contacts"
inManagedObjectContext:context];
[newContact setValue:name.text forKey:#"name"];
[newContact setValue:address.text forKey:#"address"];
[newContact setValue:phone.text forKey:#"phone"];
name.text = #"";
address.text = #"";
phone.text = #"";
NSError *error;
[context save:&error];
status.text = #"Contact saved";
}
- (void) findContact
{
coredata123AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
NSEntityDescription *entityDesc =
[NSEntityDescription entityForName:#"Contacts"
inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred =
[NSPredicate predicateWithFormat:#"(name = %#)",
name.text];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request
error:&error];
for(Contacts *info in objects)
{
NSLog(#"Name:%#",info.name);
NSLog(#"Address:%#",info.address);
}
if ([objects count] == 0) {
status.text = #"No matches";
} else {
matches = [objects objectAtIndex:0];
address.text = [matches valueForKey:#"address"];
phone.text = [matches valueForKey:#"phone"];
status.text = [NSString stringWithFormat:
#"%d matches found", [objects count]];
}
[request release];
}
And to populate the table view i have written this code..
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Contacts" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
self.contacts = [context executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
Contacts *info =[contacts objectAtIndex:indexPath.row];
cell.textLabel.text =info.name;
cell.detailTextLabel.text=info.address;
// Configure the cell...
return cell;
}
Are you getting proper number of elements in this objects array?
NSArray *objects = [context executeFetchRequest:request
error:&error];
if not, try changing the predicate with,
[NSPredicate predicateWithFormat:#"name=%#", name.text];
Otherwise, your code seems correct to me.

Best Way To Select Cell To Add To Different Table View

I have 2 views with tables. Pressing the + button on one opens the other table up in a new view and you select the cell and it should then dismiss that view and add the data to a cell in the original view.
I got the 2nd table view all set up. I have to make it so when you select the cell, it adds it to the favorite. Or maybe even select multiple cells, then press the done button, then it adds to favorites. Any ideas on how to go about this? Thanks.
EDIT:
addEvent method just for reference:
-(void)addEvent
{
Routine *routine = (Routine *)[NSEntityDescription insertNewObjectForEntityForName:#"Routine" inManagedObjectContext:managedObjectContext];
routine.name=entered;
NSError *error = nil;
if (![managedObjectContext save:&error])
{
// Handle the error.
}
NSLog(#"%#", error);
//[eventsArray addObject:routine];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSInteger lastSection = [self.routineTableView numberOfSections] -1;
[self.routineTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.routineTableView numberOfRowsInSection:lastSection]-1 inSection:lastSection] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
EDIT 2
This method is in view1, but needs to be displayed in view2, and the data is selected from view 4.
-(void)addExercise
{
Exercise *exercise = (Exercise *)[NSEntityDescription insertNewObjectForEntityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
exercise.name=entered;
NSError *error = nil;
if (![managedObjectContext save:&error])
{
// Handle the error.
}
NSLog(#"%#", error);
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSInteger lastSection = [self.routineTableView numberOfSections] -1;
[self.routineTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.routineTableView numberOfRowsInSection:lastSection]-1 inSection:lastSection] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
EDIT 3:
-(void)addExercise
{
if (managedObjectContext == nil)
{
managedObjectContext = [(CurlAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[mutableFetchResults release];
[request release];
Exercise *exercise = (Exercise *)[NSEntityDescription insertNewObjectForEntityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
exercise.name=#"Test";
if (![managedObjectContext save:&error])
{
// Handle the error.
}
NSLog(#"%#", error);
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSInteger lastSection = [self.tableView numberOfSections] -1;
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.tableView numberOfRowsInSection:lastSection]-1 inSection:lastSection] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
[tableView reloadData];
[self viewDidLoad];
}
In didSelect method of 2nd tableView you will need to update the datasource of first table and then either call reload when done button is pressed or use insertRowsAtIndex method.
Thanks,

Is there a problem with my Core Data code

I have had a customer contact me about a bug in my application which I believe is related to my use of Core Data. This is currently only a theory as I have not be able to re-create the issue myself.
The problem appears to be if the user creates a new entity object and then edits the entity object straight away it does not seem to persist correctly and the next time the user opens the application the object is not there.
If the user creates the entity object and exits the app without editing it the problem does not occur, and if the user edits the object after re-opening the app it also does not occur.
I have only had one report of this happening and the device in question is a iPhone 3G running IOS4.0.2. I can not re-create it on an iPhone 3GS, iPhone 4 or via the simulator (all running 4.0.2)
I am no Core Data expert and am wondering if there is a problem with the way I am using the framework. I would really appreciate it if someone would review the code I have below and let me know if they see any potential problems.
I have included the methods that interact with core data from the relevant classes.
AppDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSError *error = nil;
if (managedObjectContext_ != nil) {
if ([managedObjectContext_ hasChanges] && ![managedObjectContext_ save:&error]) {
// log
}
}
}
- (void)applicationWillTerminate:(UIApplication *)application {
NSError *error = nil;
if (managedObjectContext_ != nil) {
if ([managedObjectContext_ hasChanges] && ![managedObjectContext_ save:&error]) {
// log
}
}
}
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext_ != nil) {
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext_ = [[NSManagedObjectContext alloc] init];
[managedObjectContext_ setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext_;
}
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel_ != nil) {
return managedObjectModel_;
}
managedObjectModel_ = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
return managedObjectModel_;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator_ != nil) {
return persistentStoreCoordinator_;
}
NSURL *storeURL = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"mydatabase.sqlite"]];
NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"An error occurred adding the persistentStoreCoordinator. %#, %#", error, [error userInfo]);
// Display an alert message if an error occurs
}
return persistentStoreCoordinator_;
}
Controller 1 (creates the entity object using an image selected via the Image Picker)
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage* selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
// Create an image object for the new image.
NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:#"Image" inManagedObjectContext:managedObjectContext];
// Set the image for the image managed object.
[image setValue:[selectedImage scaleAndCropImageToScreenSize] forKey:#"image"];
// Create a thumbnail version of the image.
UIImage *imageThumbnail = [selectedImage thumbnailImage:50.0F];
// Create a new note
Note *note = [NSEntityDescription insertNewObjectForEntityForName:#"Note" inManagedObjectContext:managedObjectContext];
NSDate *now = [[NSDate alloc] init];
note.createdDate = now;
note.lastModifiedDate = now;
[now release];
note.thumbnail = imageThumbnail;
note.image = image;
}
[self dismissModalViewControllerAnimated:YES];
[picker release];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NotePadViewController *notePadController = [[NotePadViewController alloc] initWithNibName:#"NotePadView" bundle:nil];
Note *note = [[self fetchedResultsController] objectAtIndexPath:indexPath];
notePadController.note = note;
notePadController.title = note.notes;
[self.navigationController pushViewController:notePadController animated:YES];
[notePadController release];
}
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Note" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"createdDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
if (![fetchedResultsController performFetch:&error]) {
NSLog(#"An error occured retrieving fetched results. %#, %#", error, [error userInfo]);
// Display an alert message if an error occurs
}
return fetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self setControllerTitle];
[self.tableView endUpdates];
}
Controller 2 - Used to view and edit the entity object (add text)
- (void)saveAction:(id)sender {
NSDate *now = [[NSDate alloc] init];
if (self.note != nil && textView.text.length == 0) {
self.note.notes = nil;
self.note.lastModifiedDate = now;
} else if (textView.text.length != 0) {
// Create a new note if one does not exist
if (self.note == nil) {
VisualNotesAppDelegate *appDelegate = (VisualNotesAppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
Note *newNote = [NSEntityDescription insertNewObjectForEntityForName:#"Note" inManagedObjectContext:managedObjectContext];
self.note = newNote;
self.note.createdDate = now;
}
self.note.lastModifiedDate = now;
self.note.notes = textView.text;
self.title = [note title];
}
[now release];
[self.textView resignFirstResponder];
}
Many thanks in advance.
First, you really should not be ignoring those errors. You could be throwing an error there and never know it.
Nothing really jumps out about the code itself, but you could easily be having an error during the save, perhaps a non-optional parameter not being set, etc.
Handle the exceptions and see from there.
The problem is that I am only saving the managed object context when the app terminates or is backgrounded.
I only have about 5 seconds for all of the image blobs that were created by the user to be saved before the app exits. If there are a lot of images then they may not all save in time which is why they do not appear when the app is restarted.
This mainly effects the iPhone 3G as it is the slowest of all the models I support.
I have updated my code to save the managed context when ever a change is made. This has resolved this problem but has exposed another issue:
https://stackoverflow.com/questions/3578951/nsfetchedresultscontrollerdelegate-methods-not-being-called-when-camera-image-sav
If the entity is only created in the saveAction: method then it might not get created in the first place if the user quits the application before manually choosing save.