我在UISplitViewController
中有一个UITableViewController
。这tableViewController收到两件事情:对UITableView的一部分使用NSFetchedResultsController
- 发票
- Customer对象的数组
所以我在做什么是填充在UITableView中的第一部分(或Section 0
)发票的详细信息。
对于第二部分,我使用NSFetchedResultsController
来获取具有invoice == nil
的客户的所有属性,并在表视图的第二部分中显示该属性。
所以基本上只使用NSFetchedResultsController
而不是UITableViewController
而不是整个东西。
现在,一切工作正常。但是,当我点击第2部分的行时,我提供用户将property
添加到新发票。当我这样做,我得到这个错误:
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)
不知道为什么会这样。我明白fetchedResultsController期望Section 0,但我确定它被手动强制只使用Section 1。
的代码以供参考是:
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch (type) {
case .Insert:
if let indexPath = newIndexPath {
let editedNewIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
tableView.insertRowsAtIndexPaths([editedNewIndexPath], withRowAnimation: .Fade)
}
break;
case .Delete:
if let indexPath = indexPath {
let editedCurrentIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
tableView.deleteRowsAtIndexPaths([editedCurrentIndexPath], withRowAnimation: .Fade)
}
break;
case .Update:
if let indexPath = indexPath {
let editedCurrentIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
if let cell = tableView.cellForRowAtIndexPath(editedCurrentIndexPath){
configureCell(cell, atIndexPath: editedCurrentIndexPath)
//tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: .None)
}
}
break;
case .Move:
if let indexPath = indexPath {
let editedCurrentIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
tableView.deleteRowsAtIndexPaths([editedCurrentIndexPath], withRowAnimation: .Fade)
}
if let newIndexPath = newIndexPath {
let editedNewIndexPath = NSIndexPath(forRow: newIndexPath.row, inSection: 1)
tableView.insertRowsAtIndexPaths([editedNewIndexPath], withRowAnimation: .Fade)
}
break;
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
if let ivData = self.invoices{
print("Section0 - \(ivData.count)")
return ivData.count
}
}
else if section == 1{
if let sections = fetchedResultsController.sections {
let sectionInfo = sections[0]
print("Section1 - \(sectionInfo.numberOfObjects)")
if sectionInfo.numberOfObjects > 0{
return sectionInfo.numberOfObjects
}
else{
return 1
}
}
}
return 0
}
的代码保存新的发票是:
do{
self.invoices!.append(billRecord as! InvoiceInfo)
try billRecord.managedObjectContext?.save()
try self.customer!.managedObjectContext?.save()
try record.managedObjectContext?.save()
//self.lookUpLotsWithoutBills()
self.tableView.reloadData()
}
catch{
self.invoices!.removeObject(ivRecord)
let alertController = UIAlertController(title: "Unexpected Error", message: "Your data could not be updated. Please try again later.", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "Done", style: .Cancel, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
出了什么问题吗?
嗨,我在保存'managedObjectContext'之前调用'self.tableView.reloadData()'并在将数据追加到数组之后立即调用。但我仍然遇到同样的问题。 –
嘿,你是对的。这是发生错误的主要原因。现在,我在FRC之前调用'self.tableView.reloadData'甚至注意到这些更改及其所有工作正常。谢谢! –