在fetchedResultsController委托方法(iOS)中插入行时崩溃

时间:2016-12-07 18:43:24

标签: ios nsfetchedresultscontroller

我使用以下方法在创建新实体时使用fetchedResultsController委托更新我的tableView:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {
    case .insert:
        //Crash here
        self.tableView.insertRows(at: [newIndexPath!], with: .automatic)
    default:
        print("default")
    }
}

这样可行,但有时我会遇到以下崩溃:

 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. 

The number of rows contained in an existing section after the update (6) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). *** First throw call stack:

我正在使用fetchedResultsController。我做了一些研究,答案声称更新了numberOfRowsInSection,但是我将截面中的行数设置为fetchedResultController部分中的对象数。我尝试在&amp;之后调用reloadData()在插入行之前,但这不能解决它。这是我的numberOfRowsInSection方法:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let sections = fetchedResultsController.sections {
        let currentSection = sections[section]
        return currentSection.numberOfObjects
    }
    return 0
}

我的fetchedResultsController:

lazy var fetchedResultsController: NSFetchedResultsController<Project> = {

    let userFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Project")
    let coreDataStack = CoreDataStack.default()
    let managedContext = coreDataStack?.managedObjectContext

    let primarySortDescriptor = NSSortDescriptor(key: "dateCreated", ascending: false)
    userFetchRequest.sortDescriptors = [primarySortDescriptor]

        let frc = NSFetchedResultsController(
        fetchRequest: userFetchRequest,
        managedObjectContext: managedContext!,
        sectionNameKeyPath: nil,
        cacheName: nil)

    frc.delegate = self

    return frc as! NSFetchedResultsController<Project>
}()

// SOLUTION:
正如Zepar所提到的,这就是我必须要解决的问题。

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    self.tableView.beginUpdates()
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    self.tableView.endUpdates()
}

1 个答案:

答案 0 :(得分:1)

您忘记通知tableView内容已开始更新:

[self.tableView beginUpdates]; 

[self.tableView endUpdates]; 

修改的部分和行的数量必须与获取的部分和行一致。

查看文档,还有一个例子: https://developer.apple.com/reference/coredata/nsfetchedresultscontrollerdelegate