NSFetchedResultsController не показывает обновления из другого контекста #39;

У меня есть NSFetchedResultsControllerи несколько операций обновляют управляемые объекты в отдельных потоках через NSOperationQueue.

FRC (со своим предикатом )выглядит следующим образом.:

- (NSFetchedResultsController*)fetchedResultsController
{
    if(fetchedResultsController) return fetchedResultsController;

    NSManagedObjectContext* mainContext = [self managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Check" inManagedObjectContext:mainContext]];
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"isSync == %@", [NSNumber numberWithBool:NO]]];
    [fetchRequest setFetchBatchSize:10];

    fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:mainContext sectionNameKeyPath:nil cacheName:nil];
    fetchedResultsController.delegate = self;

    [fetchRequest release], fetchRequest = nil;

    return fetchedResultsController;
}

Основной поток и потоковая операция имеют свои собственные контексты управляемых объектов. У них только один и тот же координатор.

В поточной операции я изменяю свойство isSyncс NOна YES. Чтобы узнать, какой объект Checkнужно обновить, основной контекст передается многопоточному NSManagedObjectID. Потоковая операция извлекает управляемый объект следующим образом::

-(void)main
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSManagedObjectContext *exportContext = [[NSManagedObjectContext alloc] init];
    [exportContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];

    //...

    Check* check = (Check*)[exportContext existingObjectWithID:objID error:&error];
    check.isSync = [NSNumber numberWithBool:YES];

    //...

    [exportContext save:&error];

    [pool release], pool = nil;
}

Когда потоковая операция вызывает save, вызывается уведомление mergeChangesFromContextDidSaveNotification, и основной контекст объединяет изменения.

- (void)contextChanged:(NSNotification*)notification
{
    if ([notification object] == [self managedObjectContext]) return;

    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES];
        return;
    }

    [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}

Регистрация описания notificationприводит к проверке правильности выполнения изменений.

Моя проблема

Методы делегатов NSFetchedResultsControllerDelegateне вызываются.

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

Я нашел несколько тем на SO с той же проблемой. Я испробовал все обходные пути, но не могу найти ценного решения.:

  1. NSFetchedResultsController не показывает обновления из других контекстов

  2. NSFetchedResultsController не запускает метод делегата после слияния обновления из фонового потока

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

Заранее спасибо.

Изменить

Приведенный выше код работал в предыдущей модели. Затем я создал новую модель, скопировав (и вставив объекты )из предыдущей, и теперь она больше не работает.

Предложения?

Редактировать 2

Это предикат, который я использую в NSFetchedResultsControllerгеттере. Это моя вина, но когда я писал пост, я его не скопировал.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"insertionDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

// previous code here
[fetchRequest setSortDescriptors:sortDescriptors];

Теперь о Джоди последний комментарий

В основном ()вашего NSOperation вы загружаете новые объекты, а в там похоже, что вы устанавливаете isSync на YES для каждого нового объекта. Предикат, который вы используете для fetchedResultsController, ищет только для объектов, у которых isSync == NO.

Я ожидаю, что когда для свойства isSyncзадано значение YES, NSFetchedResultsControllerзамечает, что изменяет и удаляет строки, не соответствующие предикату. Я ошибся?

Помните, что при объединении изменений из фона в основной поток я вижу, что несколько объектов обновили свое свойство isSync.

22
задан Community 23 May 2017 в 11:51
поделиться