Reputation: 5
Using core data on a on an application that has tabbed views. The second tab loads the core data, no errors show up in Xcode or when I run the app but when I click on the second tab the app crashes with the error "An Instance of NSFetchedResultsController requires a non-nil fetch request and managedObjectContext.
I'm new to core data and really struggling with this error so would appreciate any help I can get. The implementation file has the following code
- (void)setupFetchedResultsController
{
// 1 - Decide what Entity you want
NSString *entityName = @"EatCategory"; // Put your entity name here
NSLog(@"Setting up a Fetched Results Controller for the Entity named %@", entityName);
// 2 - Request that Entity
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
// 3 - Filter it if you want
//request.predicate = [NSPredicate predicateWithFormat:@"EatCategory.name = Blah"];
// 4 - Sort it if you want
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name"
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)]];
// 5 - Fetch it
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[self performFetch];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setupFetchedResultsController];
if ([[self.fetchedResultsController fetchedObjects] count] == 0) {
NSLog(@"No Results were fetched so nothing will be given to the table view");
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Eat Category Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// configure the cell...
EatCategory *eatcategory = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = eatcategory.name;
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableView beginUpdates]; // Avoid NSInternalInconsistencyException
// Delete the role object that was swiped
EatCategory *eatCategoryToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"Deleting (%@)", eatCategoryToDelete.name);
[self.managedObjectContext deleteObject:eatCategoryToDelete];
[self.managedObjectContext save:nil];
// Delete the (now empty) row on the table
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self performFetch];
[self.tableView endUpdates];
}
}
Upvotes: 0
Views: 3179
Reputation: 33428
Are you sure you are setting the managed object context properly? It seems that the fetch request is ok but what about the context? If the context is not set properly this could lead to that error.
Do you inject the context from an external object? If yes, how is declared the managedObjectContext
property?
For example:
// from an external object
YourController *controller = ... // alloc-init the controller
controller.managedObjectContext = self.managedObjectContext;
// within your controller .h
@property (strong, nonatomic) NSManagedObject* managedObjectContext; // or retain if you don't use ARC
// within your controller .m
@synthesize managedObjectContext;
You could also grab the main context inside your controller from the application delegate (if you have declared it there) like the following:
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext* managedObjectContext = delegate.managedObjectContext;
but this could lead to a more rigid application design.
Some notes
Instead of using commitEditingStyle
you could "register" for NSFetchedResultsControllerDelegate
callbacks. This class has been created to deal with changes in table views. You could use it and respond in different manner for table changes.
Here the class reference for NSFetchedResultsControllerDelegate.
Hope it helps.
Upvotes: 1