Обновления ios coredata не видны в разных контекстах управляемого объекта - данные различаются в разных контекстах - PullRequest
5 голосов
/ 10 августа 2011

У нас есть проблема, когда разные потоки видят разные данные в одних и тех же записях, но в разных контекстах управляемого объекта (moc).Наше приложение синхронизируется в фоновом режиме с серверным API.Вся синхронизация выполняется в собственном потоке и с использованием собственного moc.Однако мы обнаружили, что при обновлении данных в основном модуле изменение данных не отображается в фоновом режиме.Есть идеи, что может случиться?Вот еще некоторые подробности: мы используем большую центральную диспетчеризацию, например, чтобы поместить операции синхронизации в свой собственный поток: мы проверили, на каких объектах очереди выполняется, и все это происходит в ожидаемой очереди.

- (void) executeSync; {

    dispatch_async(backgroundQueue, ^(void) {
        if([self isDebug])
            NSLog(@"ICSyncController: executeSync queue:%@ \n\n\n\n\n", [self queue]);


       for(id <ICSyncControllerDelegate> delegate in delegates){
           [delegate syncController:self];
       }
        if([ICAccountController sharedInstance].isLoggedIn == YES && shouldBeSyncing == YES) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 300ull * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
                [self executeSync];
            });
        }

    }); 
}

вот как мы создаем фоновый moc, и мы подтвердили, что он создан в фоновой очереди.

- (NSManagedObjectContext*)backgroundObjectContext {

    if (_backgroundObjectContext)
        return _backgroundObjectContext;

    _backgroundObjectContext = [[NSManagedObjectContext alloc] init];    
    [_backgroundObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
    [_backgroundObjectContext setStalenessInterval:0.0];

    return _backgroundObjectContext;
}

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

, запросив, я имею в виду следующее: фоновый MOC выполняет другой «запрос», чтобы получить «свежие» данные после изменения записейпо основному moc, все же данные имеют старые значения, а не обновленные значения, видимые в основном moc.

+ (NSArray *)dirtyObjectsInContext:(NSManagedObjectContext *)moc {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(memberships, $m, $m.category.name == %@ AND $m.syncStatus > %d).@count > 0", MANAGED_CATEGORY_FAVORITES, ManagedObjectSynced];

    return [self managedObjectsWithPredicate:predicate inContext:moc];
}

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

Ответы [ 2 ]

4 голосов
/ 10 августа 2011

Я использую следующий код для прослушивания изменений в контексте 2, чтобы контекст 1 оставался в актуальном состоянии:

  NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  [nc addObserver:context1
         selector:@selector(contextTwoUpdated:)
             name:NSManagedObjectContextDidSaveNotification
           object:context2];

это вызывает вызов этого метода в контексте 1, и я вызываю объединениеМетод:

- (void)contextTwoUpdated:(NSNotification *)notification {
  [context1 mergeChangesFromContextDidSaveNotification:notification];
}

побочным эффектом этого является любой NSFetchedResultsController, который подключен к context1, будет отправлять различные сообщения своему делегату, информируя его об изменениях,

никогда не пытался слушать в обоих направлениях, пока пользователь изменяет объект, а вы обновляете их для пользователя сзади - я подозреваю, что вам, возможно, придется управлять слияниями, если это так, поскольку для меня это односторонний (и все пользовательский) режим, я предполагаю, что всеобновления должны быть действительными

4 голосов
/ 10 августа 2011

Вот как это должно работать - действительно, важная роль контекста управляемого объекта - защищать вас от изменений данных, сделанных в других потоках.Представьте себе хаос, который может возникнуть, если у вас будет фоновый поток, модифицирующий те же объекты, которые использовался основным потоком, без какой-либо схемы синхронизации.

Чтение Передача изменений между контекстами , чтобы узнать, какобъединить изменения из одного контекста в другой.

...