Ios 在同一个表上使用2 NSFetchedResultsController时出现CoreData严重错误
我的问题是我得到了CoreData严重错误,但我不知道为什么。错误类似于: 我有一个显示用户列表的控制器(存储在CoreData的用户表中)。非常直截了当 在第二个视图控制器中,我从服务器检索用户列表,还检索存储在CoreData中的用户,查看本地是否已经有相同的用户(在这种情况下,我更改单元格的颜色背景),并在第一节的第一个单元格中添加标题标题 以下是如何在第一个viewController初始化构造函数中初始化fetchController:Ios 在同一个表上使用2 NSFetchedResultsController时出现CoreData严重错误,ios,swift,uitableview,core-data,nsfetchedresultscontroller,Ios,Swift,Uitableview,Core Data,Nsfetchedresultscontroller,我的问题是我得到了CoreData严重错误,但我不知道为什么。错误类似于: 我有一个显示用户列表的控制器(存储在CoreData的用户表中)。非常直截了当 在第二个视图控制器中,我从服务器检索用户列表,还检索存储在CoreData中的用户,查看本地是否已经有相同的用户(在这种情况下,我更改单元格的颜色背景),并在第一节的第一个单元格中添加标题标题 以下是如何在第一个viewController初始化构造函数中初始化fetchController: let modelMethodNameForS
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)
My tableview显示一个标题,该标题包含[0]节的第[0]行(表格顶部)
编辑
事故日志:
[;2016-03-16 18:51:10.511***在-[UITableView]中断言失败
_endCellAnimationsWithContext:,/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.29.5/UITableView.m:1720
2016-03-16 18:51:10.511核心数据:错误:严重的应用程序错误。
从的代理捕获到异常
调用时NSFetchedResultsController
-controllerDidChangeContent:。更新无效:节0中的行数无效。现有节中包含的行数
更新后(2)必须等于中包含的行数
更新之前的部分(1),加上或减去行数
从该节插入或删除(0插入,0删除)以及
或减去移入或移出该节的行数(0)
在中,0已移出)。使用userInfo(null)
从错误消息中,FRC告诉您(代理)某些内容已更改,因此您正在更新数据源数据,但您没有正确地告诉表视图有关插入/删除的信息 在这种特定情况下,已插入1项,并且未告知表视图任何插入 虽然很难说,但这可能与:
//We refresh the lists with new data from local Database
let listFriendsFilterBlock = peopleListWithOwnerFriendsFilter()
tableView?.reloadData()
因为这种刷新表的方法应该在
controllerdChangeContent
而不是didChangeObject
中实现。在重新加载之前,您应该知道更改已经完成。告诉我们您得到的严重错误消息是,行数有问题。我真的不明白异常是如何发生的ccur知道NSFetchedResultsController甚至不知道tableView(我们甚至没有在代码中给出指向它的指针)我在controllerDidChangeContent中移动了我的代码,但我仍然有问题。一个问题是我真的没有办法知道是哪个tableview触发了问题。我所知道的是,当错误发生时,带有开关盒的tableview布局会被破坏。就像tableview顶部内容插入一样,会变成一个巨大的空白。第二个问题是因为我不想在显示服务器和客户端之间混合的数据时告诉第二个视图控制器上的插入/删除…我现在更喜欢简单地刷新整个列表。为什么coredata和tableview之间存在链接?为什么第二个表更新真的是由FRC驱动的?我不确定为什么您不知道该更新哪一个更新,因为它们在不同的控制器中。第二个tableView只是使用一个数据源,该数据源是FRC获取的对象和服务器数据之间的合并。当coredata发生更改时,我请求服务器并重新加载整个表。也许我也必须在动手之前清空它?
//We refresh the lists with new data from local Database
let listFriendsFilterBlock = peopleListWithOwnerFriendsFilter()
tableView?.reloadData()