One UITableViewController with many NSFetchedResultsControllers - bad idea?
My app involves a main screen with several sorting/viewing options of a set of data. Depending on what the user chooses, I may list them, e.g. alphabetically, N most recent, or grouped somehow.
I started the app as a Core Data Table-based navigation app; my app delegate sets up the Core Data stack (unchanged generated code), gives the NSManagedObjectContext
to the controller for the initial screen, and it passes it to the UITableViewController
implementing my "list of entities".
Since my three different views of the same data all end up showing a table listing out the data, I expanded this class to have three different NSFetchedResultsControllers
, each with the one UITableViewController
instance as their delegate. Before pushing this view controller on the stack, I call a method to switch which NSFetchedResultsController
to use, e.g.
开发者_开发问答-(void)configureForMostRecent {
self.activeFetchedResultsController = self.mostRecentResultsController;
}
Now I am getting random crashes from Core Data, e.g. NSInternalInconsistencyException
and other things like that. Sometimes, I use the app and everything's fine, other times, it crashes almost instantly.
So, my instinct is that my design is just a Bad Idea(tm).
Should I basically stick to a "One UITableViewController
to one NSFetchedResultsController
" sort of model and just use other coding styles to reduce boilerplate?
Using multiple NSFetchedResultsController
instances is a perfectly valid design based on the description you have given so far.
Are you trying to use the same cache for each of these NSFetchedResultsController
instances? Are you calling -reloadData
on the table whenever you switch to a different NSFetchedResultsController
? Both of those could be causing the crash you are seeing.
Update
The delegate is not an issue but not calling -reloadData
is going to be a killer. The delegate methods really are there just to update the UITableView
when the NSFetchedResultsController changes. The fact that a reference to is passed into those delegate methods is a hint that they are designed to handle multiple
NSFetchedResultController` instances calling into them.
You could use one fetch controller, adjusting the fetch predicate and refetching as needed.
EDIT
Following my example case:
[NSFetchedResultsController deleteCacheWithName:@"MyObjectsCache"];
NSPredicate *_predicate = nil;
if (condition) {
_predicate = [NSPredicate predicateWithFormat:mySearchPredicateString];
self.currentTableView = searchDisplayController.searchResultsTableView;
}
else {
_predicate = [NSPredicate predicateWithFormat:myDefaultPredicateString];
self.currentTableView = tableView;
}
[fetchedResultsController.fetchRequest setPredicate:_predicate];
NSError *_error = nil;
if (![fetchedResultsController performFetch:&_error]) {
// handle error
}
精彩评论