Базовая ошибка сохранения данных гонки - PullRequest
1 голос
/ 17 мая 2011

У меня есть NSOperation, который обновляет данные приложений. Эта операция имеет свой собственный контекст, и изменения передаются обратно в контекст основного потока через уведомление contextDidSave.

Операция обновления удаляет объекты. Эти удаления непреднамеренно вызывают сбой. Сбой происходит, когда основной поток перезагружает UITableView одновременно с сохранением контекста обновления. Источник данных для табличного представления поддерживается NSFetchedResultsController.

Ни CoreData, ни UIKit не выводят никаких записей. Сбой SIG_ABRT возникает в tableView:cellForRowAtIndexPath: при доступе к атрибуту managedObject. Вот результат успешного обновления. Вы можете видеть, что таблица заполняется один раз, затем контекст сохраняется, что, в свою очередь, приводит к перезагрузке таблицы:

tableView:numberOfRowsInSection: rowCount = 29
tableView:cellForRowAtIndexPath: row: 0
tableView:cellForRowAtIndexPath: row: 1
tableView:cellForRowAtIndexPath: row: 2
tableView:cellForRowAtIndexPath: row: 3
tableView:cellForRowAtIndexPath: row: 4
tableView:cellForRowAtIndexPath: row: 5
tableView:cellForRowAtIndexPath: row: 6
tableView:cellForRowAtIndexPath: row: 7
tableView:cellForRowAtIndexPath: row: 8
tableView:cellForRowAtIndexPath: row: 9
Will saved update context
Did saved update context
Will merge update context
tableView:numberOfRowsInSection: rowCount = 58
Did merge update context
tableView:numberOfRowsInSection: rowCount = 29
tableView:cellForRowAtIndexPath: row: 0
tableView:cellForRowAtIndexPath: row: 1
tableView:cellForRowAtIndexPath: row: 2
tableView:cellForRowAtIndexPath: row: 3
tableView:cellForRowAtIndexPath: row: 4
tableView:cellForRowAtIndexPath: row: 5
tableView:cellForRowAtIndexPath: row: 6
tableView:cellForRowAtIndexPath: row: 7
tableView:cellForRowAtIndexPath: row: 8
tableView:cellForRowAtIndexPath: row: 9

А вот вывод, когда произошел сбой:

tableView:numberOfRowsInSection: rowCount = 29
tableView:cellForRowAtIndexPath: row: 0
tableView:cellForRowAtIndexPath: row: 1
tableView:cellForRowAtIndexPath: row: 2
Will saved update context
tableView:cellForRowAtIndexPath: row: 3
tableView:cellForRowAtIndexPath: row: 4
tableView:cellForRowAtIndexPath: row: 5

stacktrace

Я могу придумать два возможных решения:

  1. заблокировать persitentStoreCoordinator, пока обновляется табличное представление. (Это может быть сделано путем создания подкласса UITableView и переопределения reloadData для предоставления места для блокировки и разблокировки магазина)
  2. Отложить удаление до более поздней даты, например, когда приложение закрывается. (Это можно сделать, добавив атрибут isStale к сущностям или создав новую сущность Trash и добавив к ней объекты.)

Тем не менее, оба эти решения кажутся действительно хакерскими. Я что-то пропустил? Сначала я попытался сделать предварительный выбор NSFetchedResultsController всех объектов, но это невозможно. Другим возможным решением было заблокировать хранилище при использовании controllerDidChangeContent:, но проблема все еще возникает, когда перезагрузка таблицы не запускается fetchedResultsController.

1 Ответ

0 голосов
/ 18 мая 2011

Как уже упоминали другие, трассировка стека жизненно важна.Без этого мы можем только догадываться о решении.

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