我的问题是我得到CoreData严重错误,但我不知道为什么。错误类似于:
Core Data Serious Application Error at controllerDidChangeContent
我有一个显示用户列表的控制器(存储在CoreData的用户表中)。很直接。
在第二个视图控制器中,我从服务器检索用户列表,并且还检索存储在CoreData中的用户以查看我们是否已在本地拥有相同的用户(在这种情况下,我更改了Cell的颜色背景)我还在第一部分的第一个单元格中添加了一个带标题的标题。
以下是我在第一个viewController init构造函数中初始化fetchController的方法:
let modelMethodNameForSection = "firstCharOfFirstname"
let requestHelper = NSFetchRequest(entityName: modelEntityClass)
requestHelper.predicate = NSPredicate(format: "friend.groupA == YES")
requestHelper.sortDescriptors = [sortDescriptor]
let managedObjectCtx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
fetchedResultsController = NSFetchedResultsController(fetchRequest: requestHelper, managedObjectContext: managedObjectCtx, sectionNameKeyPath: modelMethodNameForSection, cacheName: nil)
以下是代表:
//MARK: - NSFetchedResultsControllerDelegate
func controllerWillChangeContent(controller: NSFetchedResultsController)
{
tableView!.beginUpdates()
}
func controllerDidChangeContent(controller: NSFetchedResultsController)
{
tableView!.endUpdates()
if let fetchedObjects = controller.fetchedObjects {
segmentedControlDelegate?.updateSegment(fetchedObjects.count, listType: ProfilePeopleListType.Friends) //listType doesn t matter here
}
}
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 {
if let cell = tableView!.cellForRowAtIndexPath(indexPath) as? UserViewCell { //We need to check that it's a UserViewCell, because it can be another class
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
}
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType)
{
switch type {
case .Insert:
tableView!.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
tableView!.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
以下是第二个viewController的代码,显示与服务器合并的结果:
let modelMethodNameForSection = "firstCharOfFirstname"
let requestHelper = NSFetchRequest(entityName: modelEntityClass)
requestHelper.predicate = NSPredicate(format: "friend.groupA == YES")
requestHelper.sortDescriptors = [sortDescriptor]
let managedObjectCtx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
fetchedResultsController = NSFetchedResultsController(fetchRequest: requestHelper, managedObjectContext: managedObjectCtx, sectionNameKeyPath: modelMethodNameForSection, cacheName: nil)
我的tableview在第[0]段(表格顶部)的行[0]中显示包含标题的标题
//MARK: - NSFetchedResultsControllerDelegate
//When the local database Friends table changes we are notified
func controllerWillChangeContent(controller: NSFetchedResultsController)
{
}
func controllerDidChangeContent(controller: NSFetchedResultsController)
{
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?)
{
//We refresh the lists with new data from local Database
let listFriendsFilterBlock = peopleListWithOwnerFriendsFilter()
tableView?.reloadData()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType)
{
//We don't have any sections in the users list merged with server data
}
修改 崩溃日志:
[; 2016-03-16 18:51:10.511 ***断言失败 - [UITableView _endCellAnimationsWithContext:],/ BuildRoot / Library / Cache / com.apple.xbs / Sources / UIKit / UIKit-3512.29.5 / UITableView.m:1720 2016-03-16 18:51:10.511 CoreData:错误:严重的应用程序错误。 从代表处获得了一个例外 NSFetchedResultsController在调用期间 -controllerDidChangeContent :.无效更新:第0部分中的行数无效。现有部分中包含的行数 更新后(2)必须等于包含的行数 更新前的那一节(1),加上或减去行数 插入或删除该部分(0插入,0删除)和加号 或减去移入或移出该部分的行数(0移动 in,0搬出去了)。 with userInfo(null)
答案 0 :(得分:0)
从错误消息中,您的FRC告诉您(代理人)某些内容已发生变化,因此您需要更新数据源数据,但是您没有正确地告知表格视图插入/删除。
在此特定情况下,已插入1个项目,并且尚未告知表格视图是否有任何插入。
虽然很难说,但这可能与:
有关//We refresh the lists with new data from local Database
let listFriendsFilterBlock = peopleListWithOwnerFriendsFilter()
tableView?.reloadData()
因为这种刷新表格的方法应该在controllerDidChangeContent
而不是didChangeObject
中实施。在重新加载之前,您应该知道更改已完成。