I’ve noticed that insertion of data with a NSFetchedResultsController in Core Data would refresh each cell in my Table View using the tableView:cellForRowAtIndexPath: method.
My application starts by fetching 100+ items from a Web Service. When they are added to the Core Data Database, a tableView:cellForRowAtIndexPath: call is made for each cell. I expect only the first 8-9 visible cells to refresh. How can I change that? The reason why this is a problem is that my application is downloading the cover image first time the tableView:cellForRowAtIndexPath is called — and when it is called for each cell, this is not a optimal solution.
EDIT1:
My code is fully based on an example from the CS 192p course at Stanford University. I’ve downloaded their Photomania.zip from lecture 14 and just inserted the tableView:willDisplayCell:forRowAtIndexPath: method which displays the items name in the log when the method is called. You can grab my code here: http://uploads.demaweb.dk/Photomania.zip.
As you will see, it looks like this method is called for each item in the table? Why?
EDIT2:
I was using this method in my NSFetchedResultsControllerDelegate from the iOS Developer Library. I found out that the withRowAnimation:UITableViewRowAnimationFade cause it to both call the cellForRowAtIndexPath and willDisplayCell for each cell. When changing it to withRowAnimation:UITableViewRowAnimationNone only the visible cells are called.
- (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;
}
}
Are you reusing your cells (i.e. providing a cell reuse identifier)?
Are you implementing the
NSFetchedResultsControllerDelegatemethods that will allow your view controller to insert/remove rows as they come “online” instead of doing a[tableView reloadData]? Within those methods you should be using ‘[UITableView insertRowsAtIndexPaths:withRowAnimation:],[UITableView deleteRowsAtIndexPaths:withRowAnimations:], etc. to adjust the referenced rows.Finally, you might move your image loading logic into the
UITableViewdelegate methodtableView:willDisplayCell:forRowAtIndexPath:instead. That way it is only be invoked when it is actually about to be displayed.