Обработка фоновых изменений с помощью NSFetchedResultsController - PullRequest
3 голосов
/ 07 июня 2010

У меня есть несколько ноющих проблем с NSFetchedResultsController и CoreData, по любому из которых я был бы очень признателен за помощь.

Проблема 1 - Обновления: я обновляю свой магазин в фоновом потоке, в результате чего определенные строки удаляются, вставляются или обновляются. Изменения объединяются в контексте основного потока с помощью метода «mergeChangesFromContextDidSaveNotification:». Вставки и удаления обновляются правильно, но обновления не обновляются (например, метка ячейки не обновляется вместе с изменением), хотя я подтвердил, что обновления проходят через contextDidSaveNotifcation, точно так же, как вставки и удаленные. Мой текущий обходной путь - временно изменить интервал устаревания контекста на 0, но это не похоже на идеальное решение.

Проблема 2 - Удаление объектов: размер пакета выборки равен 20. Если объект удаляется фоновым потоком, который находится в первых 20 строках, все работает нормально. Но если объект находится после первых 20 строк и таблица прокручивается вниз, возникает ошибка «CoreData не может выполнить ошибку». Я попытался восстановить контекст и выполнить повторную выборку frc - все безрезультатно. Примечание: В этом сценарии метод делегата frc "didChangeObject ...." не вызывается для удаления - я предполагаю, что это потому, что рассматриваемый объект не был поврежден в то время (так как он находился за пределами начального диапазона выборки) ). Но по какой-то причине контекст все еще думает, что объект находится вокруг, хотя он был удален из хранилища.

Проблема 3 - Удаление разделов: когда удаление строки приводит к удалению раздела, я получил «недопустимое количество строк в разделе ???» ошибка. Я работал над этим, удалив строку «reloadSection» из раздела NSFetchedResultsChangeMove: и заменив ее на «[tableView insertRowsAtIndexPaths ....». Кажется, это работает, но, опять же, я не уверен, что это лучшее решение.

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 2 ]

11 голосов
/ 07 июня 2010

Я думаю, что все ваши проблемы связаны с кешем выбранного контроллера результатов.

Проблема 1 вызвана тем, что FRC использует кэшированные объекты (чьи идентификаторы не изменились). Когда вы добавляете или удаляете объект, который изменяет идентификаторы и вызывает обновление кэша, но изменяет атрибуты объектане делает это надежно.

Проблема 2 вызвана проверкой FRC для объекта в кеше.Скорее всего, у объекта есть неповрежденные отношения, которые сохраняются в кеше.Когда вы удаляете его в фоновом режиме, FRC пытается выполнить сбой в объекте на другом конце отношения и не может.

Проблема 3: та же проблема.Кеш не отражает изменений.

Вы действительно не должны использовать кеш FRC, когда какой-либо объект, кроме FRC, модифицирует модель данных.У вас есть два варианта:

  1. (предпочтительнее). Не использовать кеш.При создании FRC установите для свойства cache значение nil.
  2. Очистить кэш каждый раз, когда фоновый процесс изменяет модель данных.

Конечно, два поражения цель использования кеша в первую очередь.

Кэш полезен только в том случае, если данные в значительной степени статичны и / или FRC управляет изменениями.В любых других обстоятельствах его не следует использовать, поскольку FRC необходимо повторно проверять фактическую модель данных, чтобы убедиться в ее текущем понимании данных.Он не может полагаться на копии объекта, которые он сжал, потому что другой вход мог изменить реальные объекты.

0 голосов
/ 24 июля 2012

Мой совет:

  • Определение изменений, необходимых в фоновом потоке
  • Публикация изменений в основном потоке в качестве полезной нагрузки.
  • Внести фактические изменения и сохранить в главном потоке (Контекст управляемых объектов в главном потоке)
  • НЕОБХОДИМО использовать кеш для FRC; Вы получите лучшую производительность
  • Цитата из "Pro Core Data для iOS", Майкл Приват, Роберт Уорнер:

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

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