Xcode 7 Beta 6 und und NSFetchedResultsController gab mir Kopfschmerzen heute. Wenn ich denselben (mit Swift 2 Fixes) Code mit Xcode 6 kompiliere, funktioniert das Programm auf Geräten und Simulatoren (iOS 7, iOS8). Wenn ich jedoch mit Xcode 7 Beta 6 kompiliere, stürzt das Programm auf dem Gerät (iOS 8.4) mit folgenden Fehlermeldungen ab, wenn ich Core Data aktualisiere.NSFetchedResultsController XCode 7 Problem
Ich erhalte eine Fehlermeldung ähnlich unter
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (2 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)
Manchmal mit einem anderen Fehler stürzt wie
Invalid pointer dequeued from free list *** set a breakpoint in malloc_error_break to debug
//NSFetchedResultsController delegates
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
print("Insert New: \(newIndexPath) Old: \(indexPath)")
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
case .Delete:
print("Delete New: \(newIndexPath) Old: \(indexPath)")
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
print("Update New: \(newIndexPath) Old: \(indexPath)")
tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
//self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)
case .Move:
print("Move New: \(newIndexPath) Old: \(indexPath)")
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.endUpdates()
}
für den .Update
Abschnitt Ich habe auch versucht
self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)
zu nennen
Konfigurieren Zellmethode:
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Person
//etc
}
Sortieren Descriptors
let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
Programm immer abstürzt. Nur um dieses Problem irgendwie zu stoppen, setzen Sie delagete auf null, aktualisieren Sie das Objekt und setzen Sie delagate auf self zurück.
Ist das ein Fehler? Wenn nicht, wie kann ich das verhindern? Dank
Einige Fehlerberichte mit gleichen/ähnlichen Problem
https://forums.developer.apple.com/thread/12184
https://forums.developer.apple.com/thread/4999
iOS 9 - "attempt to delete and reload the same index path"
Ich lief beide XCode6 und XCode7 Versionen und gedruckt didChangeObject
Methode hier ist der Vergleich
XCode6 iOS 8,4
Update New: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}) Old: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})
XCode 7B6 iOS 8,4
Update New: nil Old: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})
Insert New: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}) Old: Optional(<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})
2015-09-01 01:15:37.898 TestProg[3230:200562] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-3347.44.2/UITableView.m:1623
2015-09-01 01:15:37.900 TestProg[3230:200562] CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (3) must be equal to the number of rows contained in that section before the update (3), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)
In meinem aktuellen Projekt verwende ich auch die 'configureCell' Methode, ich denke ich habe sie wegen eines ähnlichen Fehlers geändert. Könnten Sie vielleicht Ihre configure-Zellen-Methode zeigen? – Mundi
es ist mosty boostplate code. Ich habe eine Beziehung von eins zu vielen. Etwas wie unten: func configureCell (Zelle: UITableViewCell, atIndexPath indexPath: NSIndexPath) { Lassen Sie object = self.fetchedResultsController.objectAtIndexPath (indexPath) as! Person // usw. } – Meanteacher
Hat Ihr FRC einen Sortierungsdeskriptor oder ein Prädikat, das sich auf eine Beziehung über den Schlüsselpfad bezieht? Das kann manchmal zu unerwarteten Ergebnissen führen. – Mundi