coredata + MagicRecords, как найти все в фоновом режиме
У меня возникла эта проблема с тех пор, как я решил получить все данные в фоновом режиме, что-то вроде этого
dispatch_async(queue, ^{
/* fetch my data here */
self.data = [SomeEntity MR_findAll];
dispatch_sync(dispatch_get_main_queue(), ^{
[self.tableview reloadData];
});
});
Он работает нормально при первом запуске, если вы заходите в другой контроллер представления и ждете пары минут, а затем возвращаетесь, все найденные объекты перешли в состояние ошибки и больше никаких атрибутов не доступны
Сначала я использовал GCD для фоновой очереди, затем я попытался создать свою собственную очередь с помощью
queue = dispatch_queue_create("com.myname.queue", DISPATCH_QUEUE_CONCURRENT);
это все еще порочит все
Я посмотрел на источники MagicRecords, кажется, он автоматически создает новый контекст для текущей темы
У меня заканчиваются идеи, пожалуйста, помогите
спасибо заранее
2 ответа
Хорошей идеей для решения этой проблемы является отказ от сторонних фреймворков, которые ведут себя непредсказуемо и не поддаются отслеживанию. Вы можете обойти это, установив по умолчанию стандартный API-интерфейс управляемого объекта.
Кажется, что MR не очень хорошо играет с табличным представлением. Данных слишком много, и основные данные порочат объекты. Вместо этого реализуйте обычный ваниль NSFetchedResultsController
и наслаждайтесь его бесплатными оптимизациями памяти, включая автоматические сбои и сбои управляемых объектов по мере необходимости.
Ты не можешь МР работает как задумано.
Интерфейс tableview работает в основном потоке, как и все элементы UIKit.
Вы не можете пересекать потоки с Core-Data, что означает, что NSManagedObjects и связанные с ними контексты принадлежат потоку, который их создал. Любая попытка перепутать потоки с Core Data в конечном итоге потерпит крах.
Таким образом, вы можете выполнять фоновую обработку в Core Data и объединяться с контекстом основного потока, но где-то вдоль линии вам нужно получить данные, которые вы представляете в пользовательском интерфейсе основного потока.
Так что вы можете сделать это...
dispatch_async(queue, ^{
[self doSomeHeavyProcessingForSomeEntityThenSaveThreadContext];
dispatch_sync(dispatch_get_main_queue(), ^{
self.data = [SomeEntity MR_findAll];
[self.tableview reloadData];
});
});