Сбой CoreData при вставке и удаление происходит одновременно - PullRequest
0 голосов
/ 19 июня 2019

Я сталкиваюсь с падением CoreData на FetchedResultsController.

Сценарий: Я пытаюсь одновременно вставить и удалить некоторые данные в FetchedResultsController. Итак, за это время авария произошла неожиданно.

Примечание: Авария случается редко.

Я попробовал некоторые ответы от StackOverflow, но ни один из них не помог мне. Поэтому было бы полезно найти решение этой проблемы.

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

 switch type {

 case .insert:
 guard let newIndexPath = newIndexPath  else { return }
 self.tableView.insertRows(at: [newIndexPath], with: rowAnimation)

 case .delete:
 guard let indexPath = indexPath else { return }
 self.tableView.deleteRows(at: [indexPath], with: .none)

 case .update:
 guard let indexPath = indexPath else { return }
 self.updateRow(atIndexpath: indexPath)

 case .move:

 guard let deleteIndexPath = indexPath, let insertIndexPath = newIndexPath, deleteIndexPath == insertIndexPath else {
    return
 }
 self.updateRow(atIndexpath: insertIndexPath)
 }
}

Отчет о сбое:

*** Ошибка подтверждения в - [AppName.tableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore/UIKit-3698.119.2/UITableView.m:1821

[ошибка] ошибка: серьезная ошибка приложения. Исключение было получено от делегата NSFetchedResultsController во время вызова -controllerDidChangeContent :. Неверное обновление: недопустимое количество строк в разделе 7. Количество строк, содержащихся в существующем разделе после обновления (4), должно быть равно числу строк, содержащихся в этом разделе до обновления (4), плюс или минус число из строк, вставленных или удаленных из этого раздела (1 вставлено, 0 удалено) и плюс или минус количество строк, перемещенных в или из этого раздела (0 перемещено, 0 перемещено). with userInfo (null)

У меня есть некоторая подсказка по этому вопросу, это происходит в tableView.endUpdates() в controllerDidChangeContent делегате.

Ответы [ 2 ]

0 голосов
/ 19 июня 2019

По сообщению о сбое, которое вы предоставили, кажется, что сбой происходит, когда есть вставка, но в табличном представлении все еще есть старое количество строк.

Как написано в документации Apple, рекомендуется выполнить серию изменений табличного представления, вложенных между вызовами методов tableView.beginUpdates() и tableView.endUpdates().

Это позволит табличному представлению синхронизировать данные, вызывая

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func numberOfSections(in tableView: UITableView) -> Int

методы и т. Д.

Таким образом, вы можете добавить tableView.beginUpdates(), tableView.endUpdates() вызовы в реализации метода NSFetchedResultsControllerDelegate

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}

Также вы неправильно обрабатываете дело .move. tableView.moveRow(at: oldIndexPath, to: newIndexPath) должен быть вызван вместо

0 голосов
/ 19 июня 2019

Вы не двигаетесь в случае .move.Существует API:

case .move: tableView.moveRow(at: indexPath!, to: newIndexPath!)

Пути принудительного развертывания безопасны, поскольку контроллер отправляет оба пути в случае .move, а также соответствующие пути в других случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...