P. Pawluś
P. Pawluś

Reputation: 318

NSFetchedResultsController returns wrong number rows in first section while inserting rows to second section

This is my NSFetchedResultsControllerDelegate with some prints:

//MARK: - NSFetchedResultsControllerDelegate

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

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {

    let indexSet = NSIndexSet(index: sectionIndex)

    switch type {
    case .Insert:

        print("SECTION INSERT --->>> \(sectionIndex)")
        tableView.insertSections(indexSet, withRowAnimation: .Fade)

    case .Delete:

        tableView.deleteSections(indexSet, withRowAnimation: .Fade)

    case .Update:

        fallthrough

    case .Move:

        tableView.reloadSections(indexSet, withRowAnimation: .Fade)
    }
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

    switch type {
    case .Insert:

        if let newIndexPath = newIndexPath {

            print("ROW INSERT --->>> \(newIndexPath)")
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
        }

    case .Delete:

        if let indexPath = indexPath {
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }

    case .Update:

        if let indexPath = indexPath {
            tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }

    case .Move:

        if let indexPath = indexPath, let newIndexPath = newIndexPath {

            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
        }
    }

    print("First sumOfRows --->>> \(fetchedResultsController.fetchedObjects?.count)")

    var sumOfRows = 0
    for section in fetchedResultsController.sections! {

       sumOfRows += section.objects!.count
    }

    print("Second sumOfRows--->>> \(sumOfRows)")
}

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

//MARK: - UITableViewDataSource

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return fetchedResultsController?.sections?.count ?? 0
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    print("Section --->>> \(section)")
    print("Number of rows in section --->>> \(fetchedResultsController.sections![section].objects!.count)")
    return fetchedResultsController.sections![section].objects!.count
}

BEFORE the insert I have only one section with one row there.

When I insert new row the output on console is following:

SECTION INSERT --->>> 1
ROW INSERT --->>> <NSIndexPath: 0xc000000000000116> {length = 2, path = 1 - 0}
First sumOfRows --->>> Optional(2)
Second sumOfRows--->>> 3
Section --->>> 0
Number of rows in section --->>> 2
Section --->>> 1
Number of rows in section --->>> 1

Error I get:

CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

Why NSFetchedResultsController returns wrong number of rows in section?

Upvotes: 0

Views: 1180

Answers (1)

Bartłomiej Semańczyk
Bartłomiej Semańczyk

Reputation: 61880

Just use numberOfObjects instead of objects!.count for your numberOfRowsInSection method.

Please see this answer.

Upvotes: 0

Related Questions