(Entity names have been changed to facilitate reading)
Environment: Xcode 7 beta 4. iOS 9.0 is the base SDK, and the deployment target is iOS 8.0. Debugging on a real iPhone 5s device with iOS 8.4.
Here is an interesting Core Data error that I spent the last couple of days debugging / trying to understand.
-
I created an object RecipeEntitythat has some attributes and a many-to-many relationship with an entity IngredientEntityto represent its ingredients. IngredientsEntityhas a corresponding inverse relation to RecipeEntity, both objects have the following properties established in the relationship:

, , , NSFetchedResultsController , NSFetchedResultsControllerDelegate - .
, :
private var deletedSectionIndexes = NSMutableIndexSet()
private var insertedSectionIndexes = NSMutableIndexSet()
private var deletedRowIndexPaths = [NSIndexPath]()
private var insertedRowIndexPaths = [NSIndexPath]()
private var updatedRowIndexPaths = [NSIndexPath]()
func controller(controller: NSFetchedResultsController, didChangeObject anObject: NSManagedObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case NSFetchedResultsChangeType.Insert:
if let newIndexPath = newIndexPath {
if insertedSectionIndexes.containsIndex(newIndexPath.section) {
return
}
insertedRowIndexPaths.append(newIndexPath)
}
case NSFetchedResultsChangeType.Delete:
if let indexPath = indexPath {
if deletedSectionIndexes.containsIndex(indexPath.section) {
return
}
deletedRowIndexPaths.append(indexPath)
}
case NSFetchedResultsChangeType.Move:
if let newIndexPath = newIndexPath {
if !insertedSectionIndexes.containsIndex(newIndexPath.section) {
insertedRowIndexPaths.append(newIndexPath)
}
}
if let indexPath = indexPath {
if !deletedSectionIndexes.containsIndex(indexPath.section) {
deletedRowIndexPaths.append(indexPath)
}
}
case NSFetchedResultsChangeType.Update:
if let indexPath = indexPath {
updatedRowIndexPaths.append(indexPath)
}
}
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case NSFetchedResultsChangeType.Insert:
insertedSectionIndexes.addIndex(sectionIndex)
case NSFetchedResultsChangeType.Delete:
deletedSectionIndexes.addIndex(sectionIndex)
default:
break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
tableView.deleteSections(deletedSectionIndexes, withRowAnimation: UITableViewRowAnimation.Automatic)
tableView.insertSections(insertedSectionIndexes, withRowAnimation: UITableViewRowAnimation.Automatic)
tableView.deleteRowsAtIndexPaths(deletedRowIndexPaths, withRowAnimation: UITableViewRowAnimation.Left)
tableView.insertRowsAtIndexPaths(insertedRowIndexPaths, withRowAnimation: UITableViewRowAnimation.Right)
tableView.reloadRowsAtIndexPaths(updatedRowIndexPaths, withRowAnimation: UITableViewRowAnimation.Automatic)
tableView.endUpdates()
insertedSectionIndexes = NSMutableIndexSet()
deletedSectionIndexes = NSMutableIndexSet()
deletedRowIndexPaths = [NSIndexPath]()
insertedRowIndexPaths = [NSIndexPath]()
updatedRowIndexPaths = [NSIndexPath]()
}
, IngredientEntity, RecipeEntity, :
2015-08-12 14: 43: 34.777 MyApp [9707: 2866157] *** - [MyApp.MyAppTableView _endCellAnimationsWithContext:],/SourceCache/UIKit/UIKit-3347.44.2/UITableView.m:1222
2015-08-12 14: 43: 34.782 MyApp [9707: 2866157] CoreData: : . NSFetchedResultsController -controllerDidChangeContent:. ({length = 2, path = 0 - 0}) userInfo (null)
controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:, NSFetchedResultsChangeType.Move, NSIndexPath indexPath newIndexPath.
, :
// setOfIngredients is an NSSet of IngredientEntity retreived from Core Data.
recipeEntity.ingredients = setOfIngredients
case case ( controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:) :
case NSFetchedResultsChangeType.Move:
if indexPath != newIndexPath {
if let newIndexPath = newIndexPath {
if !insertedSectionIndexes.containsIndex(newIndexPath.section) {
insertedRowIndexPaths.append(newIndexPath)
}
}
if let indexPath = indexPath {
if !deletedSectionIndexes.containsIndex(indexPath.section) {
deletedRowIndexPaths.append(indexPath)
}
}
} else if let indexPath = indexPath {
updatedRowIndexPaths.append(indexPath)
}
-
:
, , Core Data, controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: .Move, ?
Xcode 7 beta 4/Swift 2.0 - ?
, , , , !
, - , , , .