1

Ich habe eine sehr einfache NSFetchedResultsController, die die Daten an den Benutzer in einer UITableView zeigt, ermöglicht es dem Benutzer, eine neue Entität usw. hinzuzufügen.NSFetchedResultsController sieht keine Einfügungen (oder Updates)

Jedes Mal, wenn ich eine neue Einheit, meine App abstürzt (oder manchmal auch nur warnt) mit der folgenden Meldung hinzufügen:

CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (3) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null) 

Beachten Sie, dass auch dachte, die numberOfRows 2 bis 3 aktualisiert wurden, die Einfügung/Löschding sagt immer noch (0 inserted, 0 deleted). Also mein bestes Verständnis ist, dass die NSFetchedResultsController die Änderungen oder etwas nicht bemerkt.

für NSFetchedResultsController Mein Code ist:

func fetch(frcToFetch: NSFetchedResultsController) { 

    do { 
     try frcToFetch.performFetch() 
    } catch { 
     return 
    } 
} 

func fetchRequest() -> NSFetchRequest { 

    // Initialize Fetch Request 
    let fetchRequest = NSFetchRequest(entityName: "ItemInfo") 

    // Add Sort Descriptors 
    let nameSortDescriptor = NSSortDescriptor(key: "iName", ascending: true) 
    fetchRequest.sortDescriptors = [nameSortDescriptor] 

    return fetchRequest 
} 


func getFRC() -> NSFetchedResultsController { 

    if let context = self.context{ 
     fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: context, sectionNameKeyPath: "iName.stringGroupByFirstInitial", cacheName: nil) 
     fetchedResultsController.delegate = self 
    } 
    return fetchedResultsController 
} 

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
    tableView.beginUpdates() 
} 

func controllerDidChangeContent(controller: NSFetchedResultsController) { 
    tableView.endUpdates() 
} 

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 
    switch (type) { 
    case .Insert: 
     if let indexPath = newIndexPath { 
      tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 
     break; 
    case .Delete: 
     if let indexPath = indexPath { 
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 
     break; 
    case .Update: 
     if let indexPath = indexPath { 
      let cell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell 
      configureCell(cell, atIndexPath: indexPath) 
     } 
     break; 
    case .Move: 
     if let indexPath = indexPath { 
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 

     if let newIndexPath = newIndexPath { 
      tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
     } 
     break; 
    } 
} 

override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    if let sections = fetchedResultsController.sections { 
     return sections.count 
    } 

    return 0 
} 

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    if let sections = fetchedResultsController.sections { 
     let sectionInfo = sections[section] 
     return sectionInfo.numberOfObjects 
    } 

    return 0 
} 

Und der Code neuen Datensatz einzufügen ist:

let entity: NSEntityDescription.entityForName("ItemInfo", inManagedObjectContext: self.context!)! 

let record = NSManagedObject(entity: entity, insertIntoManagedObjectContext: self.context!) 

record.setValue(name, forKey: "iName") 
record.setValue(self.billingMode.text, forKey: "iBillingMode") 

do { 
      // Save Record 
      try record.managedObjectContext?.save() 
      try self.context!.save() 
      // Dismiss View Controller 
      dismissViewControllerAnimated(true, completion: nil) 

     } catch { 
      let saveError = error as NSError 
      print("\(saveError), \(saveError.userInfo)") 

      // Show Alert View 
      showAlertWithTitle("Unexpected Error", message: "Your data could not be saved. Please try again later.", cancelButtonTitle: "Done") 
     } 

Beachten Sie, dass die self.context Variable wird von den tatsächlichen oder Master-View-Controller übergeben, das hat NSFetchedResultsController.

+0

Könnten Sie bitte versuchen, Ihre App zu löschen und erneut ausführen? – Khuong

+0

Nun, ich kann die App nicht löschen, da sie viele Daten enthält. Ich bin gerade mitten in einem Update und die Backup-Funktionalität ist im Moment kaputt. Löschen ist also keine Option. Ich habe versucht, Build-Ordner zu säubern und laufe, aber das Problem besteht immer noch. –

+2

Beachten Sie, dass das Problem mit der Anzahl der * Abschnitte * nicht der Anzahl der * Zeilen * zusammenhängt. Haben Sie '- (void) Controller implementiert: (NSFetchedResultsController *) Controller didChangeSection: (id ) sectionInfo'? – pbasdf

Antwort

0

Beachten Sie, dass das Problem mit der Anzahl der Abschnitte nicht die Anzahl der Zeilen ist. Sie müssen implementieren:

(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo