iOS 9-“尝试删除并重新加载相同的索引路径" [英] iOS 9 - "attempt to delete and reload the same index path"

查看:121
本文介绍了iOS 9-“尝试删除并重新加载相同的索引路径"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个错误:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆