首页 > 解决方案 > CoreData - 使用获取的控制器的行数无效

问题描述

我知道这是一个常见错误,但我不明白为什么会在这里发生。在第一个 vc 中,当按下添加按钮时,用户被转到第二个 vc 以创建新记录。在第二个 vc 中,一切都很顺利,直到我尝试保存上下文。此时,第一个 vc 尝试插入新记录,并且应用程序在未保存的情况下崩溃。

第二个VC:

private func createNewRecord() {
   let newRecord = Record(context: context)
   newRecord.recordNumber = "xxxx"
   currentCustomer?.addToRecords(newRecord)
   coreData?.saveContext() //App tries to insert new record on first VC here and crashes
   fetchCurrentRecord()
} 

第一个VC:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
   switch type {
   case .insert:
      if let insertIndexPath = newIndexPath {
         recordTableView.insertRows(at: [insertIndexPath], with: .fade) //CRASH!!
      }
etc.

tableView 方法(第一个 VC):

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   return recordFetchedController.fetchedObjects?.count ?? 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! RecordCell
   let record = recordFetchedController.fetchedObjects![indexPath.row] as Record
   cell.recordNumber.text = record.recordNumber
   return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
   performSegue(withIdentifier: "EditRecordSegue", sender: self)
   tableView.deselectRow(at: indexPath, animated: true)
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
   if editingStyle == .delete {
      let record = recordFetchedController.fetchedObjects![indexPath.row] as Record
   context.delete(record)
   coreData?.saveContext()
   }
}

FetchedResultsController:

func configureFetchedController(searchString: String) {
   let customerFetchRequest = NSFetchRequest<Record>(entityName: "Record")

   let predicate = NSPredicate(format: "customer.name CONTAINS[c] %@", searchString)
   customerFetchRequest.predicate = predicate

   let firstSortDescriptor = NSSortDescriptor(key: "dateModified", ascending: false)
   customerFetchRequest.sortDescriptors = [firstSortDescriptor]

   recordFetchedController = NSFetchedResultsController<Record>(
   fetchRequest: customerFetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)  

   recordFetchedController.delegate = self
}

这是错误:更新后现有节中包含的行数 (1) 必须等于更新前该节中包含的行数 (1),加上或减去插入或删除的行数从该部分(1 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与用户信息(空)

标签: iosswiftcore-datansfetchedresultscontroller

解决方案


事实证明,这个问题与我获取的控制器代码完全无关。有一个单独的客户表在选择新客户时发送通知。第二个 VC 通过返回到第一个 VC 来响应此通知。这很好。但后来我决定在添加新记录时,客户表应该将当前选择的客户移到顶部。这产生了发送另一个通知的意外后果,导致第二个 VC 开始创建新记录,但随后立即被解雇。和崩溃。这让我觉得我需要更多地了解测试。


推荐阅读