更改 sectionNameKeyPath 属性项属性时 NSFetchedResultsController 崩溃
Posted
技术标签:
【中文标题】更改 sectionNameKeyPath 属性项属性时 NSFetchedResultsController 崩溃【英文标题】:NSFetchedResultsController crash when changing sectionNameKeyPath attribute item property 【发布时间】:2015-12-14 16:28:27 【问题描述】:我有一个由 NSFetchedResultsController 支持的 UITableView。
表格视图呈现聊天对话。
我有几个聊天对话类型(NSNumber),表格视图根据您的聊天对话类型分隔为部分,因此,如果您有 3 个对话类型,那么您的表格视图中有 3 个部分。
按日期排序的聊天对话(每个对话都包含最后一条消息)。
问题是当用户更新聊天对话类型时,应用程序崩溃并出现以下错误:
CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. *** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0] with userInfo (null)
2015-12-14 18:18:24.831 Reporty[1328:108995] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
我使用以下代码初始化 NSFetchedResultsController:
lazy var fetchedResultsController: NSFetchedResultsController =
let fetchRequest = NSFetchRequest(entityName: "ChatConversation")
fetchRequest.sortDescriptors = [
NSSortDescriptor(key: "conversationType", ascending: false),
NSSortDescriptor(key: "lastMessageDate", ascending: false)
]
let frc = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: self.chatManager.getChatMainContext(),
sectionNameKeyPath: "conversationType",
cacheName: nil)
frc.delegate = self
return frc
()
我的 NSFetchedResultsController 委托代码:
extension ChatConversationsViewController: NSFetchedResultsControllerDelegate
func controllerWillChangeContent(controller: NSFetchedResultsController)
tableView.beginUpdates()
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:
break
func controller(
controller: NSFetchedResultsController,
didChangeObject anObject: AnyObject,
atIndexPath indexPath: NSIndexPath?,
forChangeType type: NSFetchedResultsChangeType,
newIndexPath: NSIndexPath?)
switch type
case .Insert:
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
case .Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
configureCell(tableView.cellForRowAtIndexPath(indexPath!) as! ChatConversationTableViewCell, atIndexPath: indexPath!)
case .Move:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
func controllerDidChangeContent(controller: NSFetchedResultsController)
tableView.endUpdates()
使用相同的 NSManagedObjectContext 更新所有核心数据模型。
我正在使用 https://github.com/jessesquires/JSQCoreDataKit 包装器
self.stack!.mainContext.performBlockAndWait
//update the model
saveContext(self.stack!.mainContext) (result: CoreDataSaveResult) in
switch result
case .Success():
print("Success")
case .Failure(let error):
print("Error: \(error)")
有什么建议吗?
谢谢
【问题讨论】:
删除 github.com/jessesquires/JSQCoreDataKit 并直接使用 CoreData,看起来它或您的应用正在侦听 NSManagedObjectContextObjectsDidChangeNotification 通知并出现问题 是的,很难基于某些第三方框架进行调试。默默无闻比方便更重要。 【参考方案1】:NSFetchedResultsControllerDelegate
方法在 NSManagedObjectContextObjectsDidChangeNotification
处理程序中调用。你应该在你的方法实现中为这些设置断点,以便找到有问题的代码。很有可能它与操纵您的表格视图和 numberOfSectionsInTableView:
或 tableView:numberOfRowsInSection:
没有返回适当的值有关(因此这些方法中的断点也可能很有用)。
【讨论】:
以上是关于更改 sectionNameKeyPath 属性项属性时 NSFetchedResultsController 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
从关系中观察到 sectionNameKeyPath 的变化
NSFetchedResultsController、sectionNameKeyPath 和无数据日期的部分
更新现有 NSFetchedResultsController 中的 sectionNameKeyPath