NSFetchedResultsController 看不到插入(或更新)

NSFetchedResultsController does not see inserts (or updates)

我有一个非常基本的 NSFetchedResultsController,它在 UITableView 中向用户显示数据,允许用户添加新实体等等。

但是,每当我添加新实体时,我的应用程序都会崩溃(或有时只是警告)并显示以下消息:

CoreData: error: 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 (3) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)

请注意,即使 numberOfRows 已从 2 更新为 3,insertion/deletion 仍然显示 (0 inserted, 0 deleted)。所以我最好的理解是 NSFetchedResultsController 没有注意到变化或其他什么。

我的 NSFetchedResultsController 代码是:

func fetch(frcToFetch: NSFetchedResultsController) {

    do {
        try frcToFetch.performFetch()
    } catch {
        return
    }
}

func fetchRequest() -> NSFetchRequest {

    // Initialize Fetch Request
    let fetchRequest = NSFetchRequest(entityName: "ItemInfo")

    // Add Sort Descriptors
    let nameSortDescriptor = NSSortDescriptor(key: "iName", ascending: true)
    fetchRequest.sortDescriptors = [nameSortDescriptor]

    return fetchRequest
}


func getFRC() -> NSFetchedResultsController {

    if let context = self.context{
        fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: context, sectionNameKeyPath: "iName.stringGroupByFirstInitial", cacheName: nil)
        fetchedResultsController.delegate = self
    }
    return fetchedResultsController
}

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch (type) {
    case .Insert:
        if let indexPath = newIndexPath {
            tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }
        break;
    case .Delete:
        if let indexPath = indexPath {
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }
        break;
    case .Update:
        if let indexPath = indexPath {
            let cell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell
            configureCell(cell, atIndexPath: indexPath)
        }
        break;
    case .Move:
        if let indexPath = indexPath {
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }

        if let newIndexPath = newIndexPath {
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
        }
        break;
    }
}

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    if let sections = fetchedResultsController.sections {
        return sections.count
    }

    return 0
}

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

    return 0
}

插入新记录的代码是:

let entity: NSEntityDescription.entityForName("ItemInfo", inManagedObjectContext: self.context!)!

let record = NSManagedObject(entity: entity, insertIntoManagedObjectContext: self.context!)

record.setValue(name, forKey: "iName")
record.setValue(self.billingMode.text, forKey: "iBillingMode")

do {
            // Save Record
            try record.managedObjectContext?.save()
            try self.context!.save()
            // Dismiss View Controller
            dismissViewControllerAnimated(true, completion: nil)

        } catch {
            let saveError = error as NSError
            print("\(saveError), \(saveError.userInfo)")

            // Show Alert View
            showAlertWithTitle("Unexpected Error", message: "Your data could not be saved. Please try again later.", cancelButtonTitle: "Done")
        }

请注意,self.context 变量是从具有 NSFetchedResultsController 的实际或主视图控制器传递的。

请注意,问题在于 部分的数量 而不是 行的数量 。您需要实施:

(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo