NSFetchedResultsController非常缓慢

3

发生了什么:

当我创建一个新的Core Data对象时,我的应用程序会挂起大约3秒钟。该对象并不是一个大型或复杂的对象。

-

详细信息:

按下按钮后,将创建一个新对象,并设置属性,然后使用以下方法保存:

[[SharedCoreDataBackend managedObjectContext] save:&error];

这将导致NSFetchedResultsController更新如下。我已经将减速缩小到以下代码行:
- (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];
}

-

所以...

您有什么想法是问题出在哪里?是否有更多的测试或代码可以发布,以帮助解决这个问题?


你为什么不使用标准的样板委托方法(如Duncan答案中所示)? - Martin R
2个回答

5

尝试使用委托方法,例如:

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

0

对于我的Swift同行们,希望我能为你们节省几秒钟:

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()
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接