Search code examples
iosobjective-ccore-datansfetchedresultscontroller

NSFetchedResultsController VERY slow


What Happens:

My app is hanging for about 3 seconds whenever I create a new Core Data object. The object isn't a big or complex object.

-

The Details:

On the press of a button, a new object is created, has properties set, and then is saved using:

[[SharedCoreDataBackend managedObjectContext] save:&error];

This results in an NSFetchedResultsController being updated as follows. I've narrowed the slowdown to the following lines of code:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 

    [self.tableView beginUpdates];

    [self.tableView deleteRowsAtIndexPaths:self.deletedRowIndexPaths withRowAnimation:UITableViewRowAnimationNone];
    [self.tableView insertRowsAtIndexPaths:self.insertedRowIndexPaths withRowAnimation:UITableViewRowAnimationNone];
    [self.tableView reloadRowsAtIndexPaths:self.updatedRowIndexPaths withRowAnimation:UITableViewRowAnimationNone];

    [self.tableView endUpdates];
}

-

So...

Any ideas what the problem is? Are there some more tests or code I can post that would help to solve this issue?


Solution

  • Try with delegate methods like this...

    - (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:
                {    
                    [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];  
                }
                    break;
    
                case NSFetchedResultsChangeDelete:
                {   
                    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                }
                    break;
    
                case NSFetchedResultsChangeUpdate:
                {   
                    [self configureCell:tableView cell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
                }
                    break;
    
                case NSFetchedResultsChangeMove:
                {   
                    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                    [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                }
                    break;
            }
    }
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    {
            [self.tableView endUpdates];
    }