- Edit * So it seems I’ve using this for the wrong purpose and the delegate will never be called upon the initial fetch. I wanted to use this to batch process the fetch, since even though the actual fetching of data is fast, the post-processing is not. I just need to off load into a background process instead * Edit *
I create a NSFetchedResultsController in the ViewDidLoad method of a UIViewController and set the delegate to self:
self.resultsController = [[[NSFetchedResultsController alloc] initWithFetchRequest:self.fetchRequest managedObjectContext:[AppDelegate singleton].managedObjectContext sectionNameKeyPath:nil cacheName:nil] autorelease];
self.resultsController.delegate = self;
Then when the ViewController is tapped, I perform the fetch if needed:
int indexPathCount = self.indexPaths.count;
int objectCount = self.resultsController.fetchedObjects.count;
if (indexPathCount && objectCount)
{
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:self.indexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
}
else
{
NSError* error;
BOOL success = [self.resultsController performFetch:&error];
if (!success)
{
UIAlertView* alert = [[[UIAlertView alloc] initWithTitle:@"ERROR" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
[alert show];
}
}
The above code will not fetch any objects and the delegate methods are never called. If I comment out the line of code above where I assign the UIViewController as the delegate, then during the second run through of the tapped code, the objectCount will contain a the correct value.
- EDIT * The above code will now actually fetch the objects. On a second run through of the code, the objectCount is now as expected, but still no delegate methods being called. Right now my assumption is that I’m doing something bad with the memory management, but all my retain counts seem to be spot on. * EDIT*
Here is the implementation of the delegate methods, but I’ve checked the them for correctness a dozen times over:
- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller
{
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath
{
switch(type)
{
case NSFetchedResultsChangeInsert:
{
NSIndexPath* tableIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:self.section];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:tableIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.indexPaths addObject:tableIndexPath];
} break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller
{
[self.tableView endUpdates];
}
Any ideas on why the NSFetchedResultsController is not working when supplied a delegate?
Not enough information. Well, not the right information. Since you didn’t post, I’ll have to assume…
First, what does your fetch request look like? Does it properly specify the objects to fetch? Does it have a sort descriptor (a requirement for a FRC fetch request)?
Normally, you kick off the request when the view controller loads… the manual calling of inserting the data like your code show is, well, let just say unconventional,