简体   繁体   English

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

[英]How to merge changes from one child managed object context to another via a parent MOC?

Hello (actual question at the bottom). 您好(实际问题在底部)。

In iOS 5 there is the introduction of parent-child managed object contexts in CoreData. 在iOS 5中,在CoreData中引入了父子管理对象上下文。

I have a standard NSFetchedResultsController and UITableVeiwController working together to fetch a master list from the store. 我有一个标准的NSFetchedResultsController和UITableVeiwController一起工作,从商店中获取主列表。 The fetched results controller's managed object context is a child with a parent context: 获取的结果控制器的托管对象上下文是具有父上下文的子项:

// 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;
}

The table view controller presents a modal view controller to add a new record, but uses a separate managed object context to do so (this context is another child of the parent context). 表视图控制器提供了一个模态视图控制器来添加新记录,但使用单独的托管对象上下文来执行此操作(此上下文是父上下文的另一个子级)。 This context gets saved in a delegate callback in the table view controller: 此上下文保存在表视图控制器的委托回调中:

- (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];
}

Question: 题:

It was my understanding that with parent-child contexts, the parent context would get the save notification from its child, and then notify all its children. 我的理解是,通过父子上下文,父上下文将从其子项获取保存通知,然后通知其所有子项。 So in my example, the build context should trigger the parent context to tell the fetched results controller to merge the changes. 所以在我的示例中,构建上下文应该触发父上下文来告诉获取的结果控制器合并更改。

This isn't happening for me, the records are successfully created, but the fetched results controller isn't picking them up. 这种情况不会发生在我身上,记录已成功创建,但获取的结果控制器并没有将它们捡起来。 I know it used to be the case you had to implement you own merge from the save notification (as seen in CoreDataBooks ). 我知道过去你需要从保存通知中实现自己的合并(如CoreDataBooks中所示 )。 But I thought the child-parent contexts solved this issue. 但我认为孩子 - 父母的背景解决了这个问题。 I tried saving the child and then the parent, but didn't seem to make a difference. 我试图保存孩子,然后是父母,但似乎没有什么区别。 Can someone explain this to me please? 有人可以向我解释一下吗? (Note: These are not contexts on separate/background threads) (注意:这些不是单独/后台线程的上下文)

Many Thanks 非常感谢

According to the WWDC 2011 presentation for "What's new in Core Data" it says you should save like this: 根据WWDC 2011关于“核心数据有什么新内容”的演示,它说你应该像这样保存:

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

From my understanding this causes the parent to receive and merge in changes from the child context. 根据我的理解,这会导致父级从子上下文接收和合并更改。 One thing to note is that the parent and all children must be created with the same concurrency type. 需要注意的一点是,必须使用相同的并发类型创建父级和所有子级。

-- Edit removed incorrect assumption that the parent pushes changes to the children, it does not. - 编辑删除了错误的假设,即父项将更改推送给子项,但事实并非如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM