NSFetchedResultsController crash on -controllerDidChangeContent: on iPad

Originator:kkormiltsev
Number:rdar://24205241 Date Originated:15-January-2016
Status:Closed Resolved:NO
Product:iOS SDK Product Version:iOS 8.3 (12F69)
Classification:Serious Bug Reproducible:Always
 
Possible duplicates: rdar://21779132, rdar://15262692, rdar://22684413

Summary:
NSFetchedResultsController crashes on -controllerDidChangeContent: on inserting new record and saving to persistentStore. Reproducable when running iPhone app ins supporting mode on iPad.

Example code fragment given:

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {
    NSLog(@"== UPDATING indexPath (%@) newIndexPath (%@) type %i", indexPath, newIndexPath, (int)type);
    switch (type) {
        case NSFetchedResultsChangeDelete: {
            [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
            break;
        }
        case NSFetchedResultsChangeInsert: {
            [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationBottom];
            break;
        }
        case NSFetchedResultsChangeMove: {
            [self.tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
            break;
        }
        case NSFetchedResultsChangeUpdate: {
            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
            break;
        }
        default:
            break;
    }
}

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    NSLog(@"== BEGIN UPDATING");
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    NSLog(@"== END UPDATING");
    [self.tableView endUpdates];
}

Steps to Reproduce:
1. Create NSFetchedResultsController;
2. Implement NSFetchedResultsController delegate methods (like in description);
3. Implement creation of entity to which instance NSFetchedResultsController was subscribed;
4. Run code on iPad;
5. Perform save to persistant store.

Expected Results:
- (void)controller: didChangeObject: atIndexPath: forChangeType: newIndexPath: is called once and with type 1 (NSFetchedResultsChangeInsert)

Actual Results:
- (void)controller: didChangeObject: atIndexPath: forChangeType: newIndexPath: is called multilpe times with types: 4 and 3 (NSFetchedResultsChangeUpdate, NSFetchedResultsChangeMove respectively) during one "changeContent" session with the same index paths (logs file attached)

Version:
iOS 8.3 (12F69)

Notes:
In target application FetchedResults delegate was implemented in UITableViewController subclass. And FetchedResultsController was working with child managed object context.

Configuration:
iPad mini (ME279TU/A)

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!