因此,我在“ resultsTVC”中有一个FRC,它加载由CoreData字段之一(“标签”)划分为多个部分的CoreData项目列表。
如果选择结果进行编辑,则第二个“ editorTVC”将加载对象的数据。但是,如果我更改“标签”字段,则会从“ resultsTVC”中收到错误消息。
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3698.103.12/UITableView.m:2043
[error] fault: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (4) must be equal to the number of sections contained in the table view before the update (3), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)
CoreData: fault: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (4) must be equal to the number of sections contained in the table view before the update (3), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)
这是我的代码:
...
let fetchRequest: NSFetchRequest<DrugMethods> = DrugMethods.fetchRequest()
let predicate = NSPredicate(format: "child = %@", self.parentItem)
let sortDescriptorSublabel = NSSortDescriptor(key: "sublabel", ascending: true, selector: #selector(NSString.localizedStandardCompare(_:)))
fetchRequest.predicate = predicate
fetchRequest.sortDescriptor = sortDescriptorSublabel
if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) {
let context = appDelegate.persistentContainer.viewContext
fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: "label", cacheName: nil)
fetchResultController.delegate = self
do {
try fetchResultController.performFetch()
if let fetchedObjects = fetchResultController.fetchedObjects {
methods = fetchedObjects
}
} catch {
print(error)
}
}
}
// MARK: - NSFetchedResultsController
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
if let newIndexPath = newIndexPath {
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
case .delete:
if let indexPath = indexPath {
tableView.deleteRows(at: [indexPath], with: .automatic)
}
case .update:
if let indexPath = indexPath {
tableView.reloadRows(at: [indexPath], with: .automatic)
}
default:
tableView.reloadData()
}
if let fetchedObjects = controller.fetchedObjects {
methods = (fetchedObjects as? [ChildItems])!
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch type {
case .insert:
tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
case .delete:
tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
case .move:
break
case .update:
break
@unknown default:
break
}
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if let sections = fetchResultController.sections {
let currentSection = sections[section]
return currentSection.name
}
return nil
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
if let sections = fetchResultController.sections {
return sections.count
}
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let sections = fetchResultController.sections {
let currentSection = sections[section]
return currentSection.numberOfObjects
}
return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
}
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showMethodEditor" {
// Load for editing
// Get selected Method
let data = fetchResultController.object(at: tableView.indexPathForSelectedRow!)
let destinationController = segue.destination as! ProtocolEditorTableViewController
destinationController.data = data
}
}
// Table Row Selection
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showMethodEditor", sender: self)
tableView.deselectRow(at: indexPath, animated: true)
}
}
我已经在线查看了各种解决方案,但是没有用