如何通过父MOC将更改从一个子托管对象上下文合并到另一个子托管对象上下文?

时间:2012-03-20 17:01:33

标签: objective-c core-data ios5

你好(实际问题在底部)。

在iOS 5中,在CoreData中引入了父子管理对象上下文。

我有一个标准的NSFetchedResultsController和UITableVeiwController协同工作,从商店中获取主列表。获取的结果控制器的托管对象上下文是具有父上下文的子项:

// AppDelegate.m

- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    __managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

    // primary managed object context has NSPrivateQueueConcurrencyType
    [__managedObjectContext setParentContext:[self primaryObjectContext]];
    return __managedObjectContext;
}

表视图控制器提供了一个模态视图控制器来添加新记录,但使用单独的托管对象上下文来执行此操作(此上下文是父上下文的另一个子级)。此上下文保存在表视图控制器的委托回调中:

- (void)addGame
{
    // New child context

    [self setBuildManagedObectContext:[[NSManagedObjectContext alloc] init]];
    [[self buildManagedObectContext] setParentContext:[[[self team] managedObjectContext] parentContext]];

    Team *buildTeam = (Team *)[[self buildManagedObectContext] objectWithID:[[self team] objectID]];
    Game *buildGame = [NSEntityDescription insertNewObjectForEntityForName:@"Game" 
                                                inManagedObjectContext:[self buildManagedObectContext]];


    [buildGame setTeam:buildTeam];

    BuildViewController *buildVC = [[BuildViewController alloc] initWithGame:buildGame delegate:self];
    UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:buildVC];
    [[self navigationController] presentViewController:navCon animated:YES completion:nil];
}

#pragma mark - Build view controller delegate

- (void)buildViewController:(BuildViewController *)controller didFinishWithSave:(BOOL)save
{
    if (save)
    {
        NSError *error = nil;
        if (![[self buildManagedObectContext] save:&error])
        {
            NSLog(@"Error saving new game");
            abort();
        }
    }
    [self setBuildManagedObectContext:nil];
    [[self navigationController] dismissViewControllerAnimated:YES completion:nil];
}

问题:

我的理解是,在父子环境中,父上下文将从其子级获取保存通知,然后通知其所有子级。所以在我的例子中,构建上下文应该触发父上下文来告诉获取的结果控制器合并更改。

这种情况不会发生在我身上,记录已成功创建,但获取的结果控制器并没有将它们捡起来。我知道以前必须从保存通知中实现自己的合并(如CoreDataBooks中所示)。但我认为孩子 - 父母的背景解决了这个问题。我试图保存孩子,然后是父母,但似乎没有什么区别。有人可以向我解释一下吗? (注意:这些不是单独/后台线程的上下文)

非常感谢

1 个答案:

答案 0 :(得分:14)

根据WWDC 2011关于“核心数据有什么新内容”的演示,它说你应该这样保存:

[child save:&error]; 
[parent performBlock:^{
    [parent save:&parentError];
}];

根据我的理解,这会导致父级从子上下文接收和合并更改。需要注意的一点是,必须使用相同的并发类型创建父级和所有子级。

- 编辑删除了错误的假设,即父级将更改推送给子级,但不是。