更新对象/节时,Swift NSFetchedResultsController崩溃

时间:2019-06-13 09:33:35

标签: swift uitableview nsfetchedresultscontroller nsfetchrequest

因此,我在“ 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)
    }

}

我已经在线查看了各种解决方案,但是没有用

0 个答案:

没有答案
相关问题