Подтвердить что ты не робот

NSFetchedResultsController с предикатом игнорирует изменения, объединенные из разных NSManagedObjectContext

Я представляю содержимое таблицы, используя NSFetchedResultsController, у которого есть предикат:

[NSPredicate predicateWithFormat:@"visible == %@", [NSNumber numberWithBool:YES]]

В фоновом потоке с использованием отдельного NSManagedObjectContext я обновляю несколько объектов и изменяю их значение visible от NO до YES. Сохранить, объединить изменения основного потока NSManagedObjectContext. Но NSFetchedResultsController fetchedObjects не изменяется. Кроме того, контроллер не вызывает -controller:didChangeObject:... для делегата. Если сущности обновляются в основном потоке одинаковым образом (мое тестовое приложение вызывает тот же метод), все работает так, как ожидалось.

Также Notification NSUpdatedObjectsKey содержит эти объекты.

В настоящее время единственными решениями, которые я нашел, является вызов для каждого из объектов NSUpdatedObjectsKey:

NSManagedObjectContext *context = ... // main thread context
[context existingObjectWithID:[object objectID] error:nil]

Эта проблема связана только с обновленными объектами, которые ранее не соответствовали предикату.

Я пропустил что-то очевидное?

4b9b3361

Ответ 1

Выключает основной NSManagedObjectContext не событие fire NSManagedObjectContextObjectsDidChangeNotification для обновленных объектов, потому что он не выполняется для поврежденных объектов.

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

NSManagedObjectContext *context = [self managedObjectContext];
for(NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey]) {
  [[context objectWithID:[object objectID]] willAccessValueForKey:nil];
}

[context mergeChangesFromContextDidSaveNotification:notification];

Из Ссылка на класс NSManagedObject:

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

Ответ 2

Вы должны вызвать processPendingChanges в Background-NSManagedObjectContext после того, как вы объединили изменения из другого NSManagedObjectContext.

См. Руководство по программированию CoreData:

Обратите внимание, что уведомление об изменении отправляется в NSManagedObjectContexts processPendingChanges метод. Основной поток привязан к событию цикла для приложения, так что вызывается processPendingChanges автоматически после каждого пользовательского события в контекстах, принадлежащих основному нить. Это не относится к фоновым потокам - когда метод invoked зависит как от платформы, так и от версии, поэтому вы не должны полагаться на определенные сроки. Если вторичный контекст не в основной теме, вы должны вызвать processPendingChanges самостоятельно подходящие соединения.