I have a single section result. I can access objects using [[fetchedResultsController fetchedObjects] objectAtIndex:index] for all objects. But it fails when I use objectAtIndexPath as follows: [fetchedResultsController objectAtIndexpath:indexPath]
Error after entering a row (for one of the SearchResult objects) in the corresponding table. It seems that the object is correctly inserted into the new table. After I visually confirm this, I select one of the lines, and then the fun begins.
Here is the code where the error occurs:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { SearchResult *event; NSLog(@"Number of sections in fetchedResultsController: %d", [[fetchedResultsController sections] count]); for (NSUInteger i=0; i<[[fetchedResultsController fetchedObjects] count]; i++) { event = (SearchResult*)[[fetchedResultsController fetchedObjects] objectAtIndex:i]; NSLog(@"object at index[%d]: %@", i, event.title ); NSLog(@"indexPath for object at index[%d]:%@", i, [fetchedResultsController indexPathForObject:event]); } NSLog(@"indexPath passed to method: %@", indexPath); SearchResult *result = [fetchedResultsController objectAtIndexPath:indexPath]; // *** here is where the error occurs *** [viewDelegate getDetails:result]; }
I have a crash in the last line. The log is as follows:
Number of sections in fetchedResultsController: 1 object at index[0]: Cirles indexPath for object at index[0]:(null) object at index[1]: Begin indexPath for object at index[1]:(null) object at index[2]: Copy indexPath for object at index[2]:(null) object at index[3]: Unbound indexPath for object at index[3]:(null) indexPath passed to method: <NSIndexPath 0x64ddea0> 2 indexes [0, 2]
After executing the NSLog instructions, I get an exception on the last line using [fetchedResultsController objectAtIndexpath:indexPath] . This happens for other index values, but they always look valid.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 2 in section at index 0'
So, to summarize, it seems that there is the correct number of selected objects, there is one section (0), I can access each of them with one method, but not the other. IndexPathForObject: always returns (null).
Is this a mistake or am I not understanding something?
UPDATE
Here is the code that implements the NSFetchedResultsControllerDelegate protocol methods.
- (void) controllerWillChangeContent:(NSFetchedResultsController *)controller { NSLog(@"Favorites controllerWillChangeContent"); [self.tableView beginUpdates]; } - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { NSLog(@"Favorites Table controllerDidChangeContent"); [self.tableView endUpdates]; } - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { NSLog(@"Favorites Changed Object"); switch (type) { case NSFetchedResultsChangeInsert: NSLog(@"--- Favorite was inserted"); if ([[self.fetchedResultsController fetchedObjects] count] == 1) { // configure first cell to replace the empty list indicator by first deleting the "empty" row [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone]; } [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone]; break; case NSFetchedResultsChangeDelete: NSLog(@"--- Favorite was deleted"); [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; if ([[self.fetchedResultsController fetchedObjects] count] == 0) { // configure first cell to show that we have an empty list [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; } break; case NSFetchedResultsChangeMove: NSLog(@"--- Favorite was moved"); break; case NSFetchedResultsChangeUpdate: NSLog(@"--- Favorite was updated"); [self configureCell:(ResultCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; break; default: break; } } - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { switch (type) { case NSFetchedResultsChangeInsert: NSLog(@"Favorites Section Added"); break; case NSFetchedResultsChangeDelete: NSLog(@"Favorites Section Deleted"); break; default: break; } }
UPDATE 2
I don't know if this matters, but the tableView is initialized with this line:
tableView = [[UITableView alloc] initWithFrame:CGRectMake(...) style:UITableViewStyleGrouped];
UPDATE 3
When I change the violation line as follows, it works fine. But I would rather keep the indexing the same as with the table.
//SearchResult *result = [self.fetchedResultsController objectAtIndexPath:indexPath]; SearchResult *result = [[self.fetchedResultsController fetchedObjects] objectAtIndex:[indexPath indexAtPosition:1]]