performBlockAndWait:同步保存根管理对象上下文不提供非临时对象ID

时间:2011-10-28 02:07:32

标签: iphone objective-c ios core-data ios5

根据iOS5发行说明和WWDC2011演示示例,我将根管理对象上下文设置为 NSPrivateQueueConcurrencyType 类型。我有一个子上下文,其类型为 NSMainQueueConcurrencyType (称为默认上下文)。

当我保存子上下文时,然后使用块API保存根上下文:performBlockAndWait:,我期望通过同步操作。

也就是说,在执行此块之后,我应该能够为刚刚插入数据存储的所有对象获取非临时的 ObjectID

但是,我改为获取临时对象ID!好像performBlockAndWait:退化为performBlock:并运行异步。但为什么呢?

这是一个错误,还是我错过了一些关键假设?

以下是一些相关代码:

// Setup of the root MOC:
__rootContext = [[NSManagedObjectContext alloc] 
    initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[__rootContext setPersistentStoreCoordinator:[self coordinator]];

// Setup of the child MOC; I use it as the "default" context:
__defaultContext = [[NSManagedObjectContext alloc] 
    initWithConcurrencyType:NSMainQueueConcurrencyType];
[__defaultContext setParentContext:__rootContext];

// Here's the essence of the save operation:
[__defaultContext save:&error]

// Setup a block I can invoke that does the save:
void (^rootContextSaveOperation)(void) = ^{
    NSError *rootContextError = nil;
    BOOL wasRootContextSaveSuccessful = [rootContext save:&rootContextError];
    if (!wasRootContextSaveSuccessful) { 
        NSLog(@"RPDataStore: Error saving root context."); }
    };

// Call perform block and wait with the operation:
[__rootContext performBlockAndWait:rootContextSaveOperation];

// Now when I inspect one of the objects just saved, I have this check in my unit test:
BOOL isTempID = [[user objectID] isTemporaryID];

问题是,对于MOC层次结构的“用户”对象部分刚从它的叶子MOC保存到根,不幸的是“isTempID”标志显示“是”。

我的期望是我可以同步执行保存以获取我可以在其他上下文中使用的永久对象ID。

我对performBlockAndWait:的概念期望是否不正确?

如果是这样,我如何与此MOC队列配置同步保存并仍然立即获得非临时ObjectID?

1 个答案:

答案 0 :(得分:2)

对于谁可能有帮助,我的解决方法是为托管对象构建一个fetch谓词,以便唯一地检索它。

我对根管理对象上下文执行此提取,然后,我可靠地获取我之前保存的托管对象的非临时对象ID。就我而言,我已经有了托管对象,可以报告在搜索中可以使用哪些密钥集,这些密钥可以唯一地识别它们。

另一个选项是在子上下文的初始保存之前获取上下文中所有对象的永久对象ID。然后,您可以使用NSManagedObjectContext的refreshObject:mergeChanges:刷新范围中特定对象的当前引用。现在它将反映刚刚保存在子环境中的更改。

使用NSManagedObjectContext的方法obtainPermanentIDsForObjects:error:

获取永久对象ID