Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 9 - "attempt to delete and reload the same index path"

This is an error:

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)

This is my typical 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() } 

in 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()     } } 
like image 695
Bartłomiej Semańczyk Avatar asked Jul 13 '15 12:07

Bartłomiej Semańczyk


1 Answers

This seems to be a bug in iOS 9 (which is still beta) and is also discussed in the Apple Developer Forum

  • iOS 9 CoreData NSFetchedResultsController update causes blank rows in UICollectionView/UITableView

I can confirm the problem with the iOS 9 Simulator from Xcode 7 beta 3. I observed that for an updated managed object, the didChangeObject: delegate method is called twice: Once with the NSFetchedResultsChangeUpdate event and then again with the NSFetchedResultsChangeMove event (and indexPath == newIndexPath).

Adding an explicit check for indexPath != newIndexPath as suggested in the above thread seems to solve the problem:

        case .Move:             if indexPath != newIndexPath {                 tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)                 tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)         } 
like image 143
Martin R Avatar answered Nov 09 '22 18:11

Martin R