In my app, data is stored into core data in the background. The main managedobjectcontext(in appdelegate) is notified about each background saving through notification method. I'm displaying the data in a tableview. I used nsfetchedrequestcontroller to auto update the tableview. I used the same managedobjectcontext in the appdelegate for fetchedresultscontroller. I get the data as expected and the tableview is getting updated for each saving of data in the background. But sometimes the tableview is getting blank with just one or two cells. I googled much about the problem and found that fault data was being rendered. So I changed the managedobjectcontext for fetchedresultscontroller to a new managedobjectcontext as told in the link below.
NSFetchedResultsController delegate fired even when context not saved
After doing it I'm not getting blank cells but the tableview is not automatically updating. How can I auto update the tableview?
-(NSFetchedResultsController*)mfetchedResultsController
{
if (_mfetchedResultsController != nil) {
return _mfetchedResultsController;
}
NSString *loginUser=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];
AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
//NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = [sharedDelegate persistentStoreCoordinator];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThreadInfo"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"threadDate" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"userEmail == %@",loginUser];
[fetchRequest setPredicate:threadPredicate];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context sectionNameKeyPath:nil
cacheName:nil];
_mfetchedResultsController = theFetchedResultsController;
_mfetchedResultsController.delegate = self;
return _mfetchedResultsController;
}
Also I'm getting this warning in my console when Tableview is getting blank with just one or two cells LOG:
2015-06-19 09:58:43.259[17460:1401522] CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. *** -[_PFBatchFaultingArray objectAtIndex:]: index (0) beyond bounds (0) with userInfo (null)
I think you are not creating the context correctly in your fetched results controller. You should use the
NSManagedObjectContext
APIinitWithConcurrencyType
and assign a parent controller.Also, I think you should not create a new context each time you create the fetched results controller. Your delegate crash is likely caused by this constellation.
The fetched results controller's context should be on the main thread, and you should only have one main thread context, so perhaps it would be better to have the class providing your core data stack (I see it is the app delegate) provide you with always the same main context.