iOS 9-“尝试删除并重新加载相同的索引路径" [英] iOS 9 - "attempt to delete and reload the same index path"
问题描述
这是一个错误:
CoreData:错误:严重的应用程序错误.在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托捕获了一个异常.尝试使用userInfo(空)删除并重新加载相同的索引路径({length = 2,path = 0-0})
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. attempt to delete and reload the same index path ( {length = 2, path = 0 - 0}) with userInfo (null)
这是我典型的NSFetchedResultsControllerDelegate
:
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
let indexSet = NSIndexSet(index: sectionIndex)
switch type {
case .Insert:
tableView.insertSections(indexSet, withRowAnimation: .Fade)
case .Delete:
tableView.deleteSections(indexSet, withRowAnimation: .Fade)
case .Update:
fallthrough
case .Move:
tableView.reloadSections(indexSet, withRowAnimation: .Fade)
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: NSManagedObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
if let newIndexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
}
case .Delete:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
case .Update:
if let indexPath = indexPath {
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}
case .Move:
if let indexPath = indexPath {
if let newIndexPath = newIndexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
}
}
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
viewDidLoad()
中:
private func setupOnceFetchedResultsController() {
if fetchedResultsController == nil {
let context = NSManagedObjectContext.MR_defaultContext()
let fetchReguest = NSFetchRequest(entityName: "DBOrder")
let dateDescriptor = NSSortDescriptor(key: "date", ascending: false)
fetchReguest.predicate = NSPredicate(format: "user.identifier = %@", DBAppSettings.currentUser!.identifier )
fetchReguest.sortDescriptors = [dateDescriptor]
fetchReguest.fetchLimit = 10
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchReguest, managedObjectContext: context, sectionNameKeyPath: "identifier", cacheName: nil)
fetchedResultsController.delegate = self
try! fetchedResultsController.performFetch()
}
}
推荐答案
由于某些原因,NSFetchedResultsController
调用.Update
,然后在调用controllerWillChangeContent:
之后调用.Move
.
For some reason NSFetchedResultsController
calls .Update
followed by .Move
after controllerWillChangeContent:
is called.
看起来就像这样: BEGIN UPDATES -> UPDATE -> MOVE -> END UPDATES .
Simply it looks like this: BEGIN UPDATES -> UPDATE -> MOVE -> END UPDATES.
仅在iOS 8.x下发生
Happens only under iOS 8.x
在一个更新会话期间,将重新加载和删除同一单元格,从而导致崩溃.
During one session of update the same cell is reloaded and deleted what cause a crash.
最简单的修复方法:
以下代码部分:
case .Update:
if let indexPath = indexPath {
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
替换为:
case .Update:
if let indexPath = indexPath {
// 1. get your cell
// 2. get object related to your cell from fetched results controller
// 3. update your cell using that object
//EXAMPLE:
if let cell = tableView.cellForRowAtIndexPath(indexPath) as? WLTableViewCell { //1
let wishlist = fetchedResultsController.objectAtIndexPath(indexPath) as! WLWishlist //2
cell.configureCellWithWishlist(wishlist) //3
}
}
真正有效的.
这篇关于iOS 9-“尝试删除并重新加载相同的索引路径"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!