1

У меня есть очень простой NSFetchedResultsController, который показывает данные пользователю в UITableView, позволяет пользователю добавлять новую сущность и т. Д.NSFetchedResultsController не видит вставки (или обновления)

Однако всякий раз, когда я добавить новый объект, мое приложение падает (или иногда просто предупреждает) со следующим сообщением:

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) 

Обратите внимание, что даже думал, что numberOfRows были обновлены от 2 до 3, вставка/удаление вещь все еще говорит (0 inserted, 0 deleted). Поэтому я лучше всего понимаю, что NSFetchedResultsController не замечает изменений или чего-то еще.

Мой код NSFetchedResultsController является:

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 
} 

А код для вставки новой записи:

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") 
     } 

Обратите внимание, что переменная self.context передается от фактического или главного контроллера представления, на котором установлен NSFetchedResultsController.

+0

Не могли бы вы попробовать удалить приложение и запустить его снова? – Khuong

+0

Ну, я не могу удалить приложение, поскольку оно содержит много данных. Я нахожусь в середине обновления, и функция резервного копирования в данный момент нарушена. Поэтому удаление не является вариантом. Я попытался «Очистить сборку» и запустить, но проблема все еще сохраняется. –

+2

Обратите внимание, что проблема связана с числом * разделов *, а не количеством * строк *. Вы реализовали контроллер '- (void): (NSFetchedResultsController *) controller didChangeSection: (id ) sectionInfo'? – pbasdf

ответ

0

Обратите внимание, что проблема заключается в количестве разделов не число строк. Вам необходимо реализовать:

(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
Смежные вопросы