在不同的托管对象上下文中看不到ios coredata更新 - 上下文之间的数据不同

Eri*_*a F 5 core-data objective-c grand-central-dispatch ios

我们遇到这个问题,其中不同的线程在相同的记录上看到不同的数据,但具有不同的托管对象上下文(moc).我们的应用程序在后台同步到服务器API.所有的同步都是在它自己的线程上完成并使用它自己的moc.但是,我们发现当数据在主moc上更新时,数据中的更改未显示在后台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];
            });
        }

    }); 
}
Run Code Online (Sandbox Code Playgroud)

这是我们如何创建背景moc,我们已经确认它是在后台队列中创建的.

- (NSManagedObjectContext*)backgroundObjectContext {

    if (_backgroundObjectContext)
        return _backgroundObjectContext;

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

    return _backgroundObjectContext;
}
Run Code Online (Sandbox Code Playgroud)

我应该补充一点,我们的后台moc正在重新查询数据,那些从该操作返回的记录仍然具有某些字段的旧值.后台moc如何获取主moc已保存的当前数据?我以为只是通过重新考验我会得到这些记录的当前状态..

通过requerying我的意思是:背景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];
}
Run Code Online (Sandbox Code Playgroud)

我们非常感谢您的帮助,因为我们一直试图解决这个问题,或者找到一个解决方案,但不包括现在放弃我们的线程.

Cal*_*leb 4

这就是它应该如何工作的——事实上,托管对象上下文的一个重要作用是保护您免受其他线程中所做数据的更改。想象一下,如果您有一个后台线程在没有某种同步方案的情况下修改主线程正在使用的相同对象,将会导致严重的破坏。

阅读在上下文之间通信更改以了解如何将更改从一个上下文合并到另一个上下文中。