【问题标题】:NSFetchedResultsController VERY slowNSFetchedResultsController 非常慢
【发布时间】:2014-01-11 02:54:33
【问题描述】:

会发生什么:

每当我创建一个新的 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];
}

-

那么...

任何想法是什么问题?我可以发布更多有助于解决此问题的测试或代码吗?

【问题讨论】:

  • 有什么理由不使用标准的样板委托方法(如邓肯的回答所示)?

标签: ios objective-c core-data nsfetchedresultscontroller


【解决方案1】:

试试这样的委托方法...

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

【讨论】:

    【解决方案2】:

    希望我能为我的 Swifters 同胞节省几秒钟的时间:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      • 2017-12-12
      • 2015-06-14
      • 2013-05-14
      • 2021-05-24
      • 1970-01-01
      • 2013-06-24
      相关资源
      最近更新 更多