简体   繁体   中英

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?

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];
}

For my fellow Swifters hopefully I can save you a few seconds:

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    myTableView?.beginUpdates()
}


func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch(type) {
        case .Insert:
            self.myTableView?.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
        case .Delete:
            self.myTableView?.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        case .Update:  
           self.configureCell((myTableView?.cellForRowAtIndexPath(indexPath!)), atIndexPath: indexPath!)
        case .Move:
                myTableView?.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
                myTableView?.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    }
}

func configureCell(cell: UITableViewCell?,
    atIndexPath indexPath: NSIndexPath) {
    //YOUR CELL UPDATE CODE
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    myTableView?.endUpdates()
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM