For a long time I’ve been getting a strange bug where most of my table view becomes black (only a few cells remain http://cl.ly/LFlS) and in other views (connected to the same MOC) some other visual glitches appear: http://cl.ly/LH3c (notice the duplicate section headers). I always figured it was a bug with CoreData but I never got to reproduce it until today while it was hooked to the debugger. Here’s the exception I got right before it happened:
CoreData: error: Serious application error. An exception was caught
from the delegate of NSFetchedResultsController during a call to
-controllerDidChangeContent:. * -[__NSArrayM insertObject:atIndex:]: object cannot be nil with userInfo (null)
It stopped on the [tableView endUpdates] line in my controllerDidChangeContent: method. Then if I click continue, the app doesn’t crash, but user interaction becomes extremely sluggish. I looked all over the place as of what might be the cause of that exception and couldn’t find anything. Any clue?
My NSFetchedResultsController change handling looks pretty much like Apple’s boilerplate. The init of my NSFRC looks like this:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Artist" inManagedObjectContext:[SWDataManager sharedManager].mainObjectContext];
[request setEntity:entity];
[request setFetchBatchSize:100];
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"sortName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
[request setSortDescriptors:@[sortByName]];
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:mainObjectContext
sectionNameKeyPath:@"firstLetter"
cacheName:nil];
fetchedResultsController.delegate = self;
[self refreshDataSource]; // set fetch request predicate and call performFetch on NSFRC
return fetchedResultsController;
EDIT: I can add that this definitely happened after that a bunch of objects got deleted from my MOC and therefore from the table view.
As requested, my controllerDidChangeContent: code:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
// this updates the section index and footer cell and other kind of stuff
[self performSelector:@selector(layoutSpecialCells) withObject:nil afterDelay:0.3];
}
I ended up requesting a TSI with Apple and here’s the gist of the answer I got:
So basically that exception is thrown by my code, and not necessarily by the Core Data framework. I still couldn’t find the root cause of the exception, so the advice:
went a long way and I realized some of my Core Data code wasn’t encapsulated inside
performBlock:calls. Once I got that fixed, I never saw the issue happen again.