核心数据 - 与NSFetchedResultsController

时间:2016-06-16 10:06:10

标签: ios swift core-data nsfetchedresultscontroller

代码

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

    return 0
}

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

    return 3
}

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

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

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    print("didChangeObject: \(indexPath?.row), \(newIndexPath?.row)")
    var _indexPath, _newIndexPath: NSIndexPath?
    if let path = indexPath {
        _indexPath = NSIndexPath(forRow: path.row + 3, inSection: path.section)
    }
    if let path = newIndexPath {
        _newIndexPath = NSIndexPath(forRow: path.row + 3, inSection: path.section)
    }

    switch type {
        case .Insert:
            print("insert: \(_indexPath?.row), \(_newIndexPath?.row), \(self.fetchedResultsController.sections?[0].numberOfObjects)")
            self.tableView.insertRowsAtIndexPaths([_indexPath!], withRowAnimation: .Fade)
            break
        case .Update:
            print("update: \(_indexPath?.row), \(_newIndexPath?.row)")
            self.tableView.reloadRowsAtIndexPaths([_indexPath!], withRowAnimation: .Fade)
            break
        case .Delete:
            print("delete: \(_indexPath?.row), \(_newIndexPath?.row)")
            self.tableView.deleteRowsAtIndexPaths([_indexPath!], withRowAnimation: .Fade)
            break
        case .Move:
            print("move: \(_indexPath?.row), \(_newIndexPath?.row)")
            if _indexPath?.row != _newIndexPath?.row {
                self.tableView.moveRowAtIndexPath(_indexPath!, toIndexPath: _newIndexPath!)
            }
            break
    }
}

每行都有一个按钮。该按钮上的点击事件会触发NSManagedObjectContext中的更新:

chat?.managedObjectContext?.performBlockAndWait({
    let mutableData = chat?.data?.mutableCopy() as? NSMutableDictionary
    mutableData?.setObject(true, forKey: "isAnswered")
    chat?.data = mutableData?.copy() as? NSDictionary
    do {
        if chat?.managedObjectContext?.hasChanges == true {
            try chat?.managedObjectContext?.save()
        }
    } catch {
        print("Unable to save: \(error)")
    }
})

场景1: 当列表中的最后一个NSManagedObject有任何更新时(有NSManagedObject + 3 {{1} s),日志如下:

String

场景2: 当除了最后一行之外的其他行中有controllerWillChangeContent didChangeObject: Optional(328), nil update: Optional(331), nil didChangeObject: Optional(328), Optional(328) insert: Optional(331), Optional(331), Optional(329) controllerDidChangeContent *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-3347.44.2.2/UITableView.m:1406 CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. attempt to insert row 332 into section 0, but there are only 332 rows in section 0 after the update with userInfo (null) 时,日志为:

update

问题:

  1. 当对象中只有controllerWillChangeContent didChangeObject: Optional(325), nil update: Optional(328), nil didChangeObject: Optional(325), Optional(325) insert: Optional(328), Optional(328), Optional(329) controllerDidChangeContent *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-3347.44.2.2/UITableView.m:1623 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 (332) must be equal to the number of rows contained in that section before the update (332), plus or minus the number of rows inserted or deleted from that section (2 inserted, 1 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) 时,为什么NSFetchedResultsController会触发update + insert
  2. 行没有刷新,我该怎么办?和
  3. 如何解决这些警告?

0 个答案:

没有答案