Core Data - 如何在不同的上下文中建立两个对象之间的关系

Posted

技术标签:

【中文标题】Core Data - 如何在不同的上下文中建立两个对象之间的关系【英文标题】:Core Data - How to establish relationship between two objects in different contexts 【发布时间】:2011-10-12 10:21:52 【问题描述】:

在我的应用程序中,我有以下 CoreData 模型:一个 Foo 有许多 Bar 实体:Foo > Bar.

为了添加一个新的 Foo 实体,我创建了一个新的 MOC,我在其中创建了一个新的 Foo 实例。这将显示 AddFooViewController。在这里,我可以为这个创建的 Foo 实体取消或保存或添加一个新的 Bar 实体。当我添加一个新的 Bar 实体时会出现问题。

让我详细解释一下:新的 Bar 实体是在一个全新的 MOC 中创建的。然后,当我决定保存 Bar 实体时,我尝试合并“Add Bar MOC”和“Add Foo MOC”。这应该通过这段代码来完成:

- (IBAction)addNewBar 
    BarAddViewController *addViewController = [[BarAddViewController alloc] initWithStyle:UITableViewStyleGrouped];

    NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
    self.addingManagedObjectContext = addingContext;
    [addingContext release];


    [addingManagedObjectContext setPersistentStoreCoordinator:[self.managedObjectContext persistentStoreCoordinator]];

    // Create new bar
    Bar *bar = (Bar *)[NSEntityDescription insertNewObjectForEntityForName:@"Bar"                                                                      inManagedObjectContext:self.addingManagedObjectContext];
    bar.creationDate = [NSDate date];


    addViewController.delegate = self;
    addViewController.bar = bar;

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addViewController];
    [self.navigationController presentModalViewController:navController animated:YES];

    [addViewController release];
    [navController release];


// Delegate method :
- (void)barAddViewController:(BarAddViewController *)controller didFinishWithSave:(BOOL)save     
    // Dismiss the modal view to return to the main list
    [self dismissModalViewControllerAnimated:YES];

    // Save modifications
    if (save) 
        NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
        [dnc addObserver:self
                selector:@selector(addBarControllerContextDidSave:) 
                    name:NSManagedObjectContextDidSaveNotification 
                  object:addingManagedObjectContext];

        // Assign relationship here ???? foo.bars = bar;

        NSError *error;
        if (![addingManagedObjectContext save:&error]) 
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        

        [dnc removeObserver:self 
                       name:NSManagedObjectContextDidSaveNotification 
                     object:addingManagedObjectContext];
     else 
        // Remove bar from addingManagedObjectContext
        [self.addingManagedObjectContext deleteObject:controller.bar];

        NSError *error;
        if (![addingManagedObjectContext save:&error]) 
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        
    

    // Release the adding managed object context.
    self.addingManagedObjectContext = nil;


- (void)addBarControllerContextDidSave:(NSNotification*)saveNotification    
    [self.managedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification];

我的问题是我不知道在哪里建立 Foo 和 Bar 之间的关系。我知道我只能在同一上下文中的两个 NSManagedObject 之间建立关系。有人可以帮帮我吗?

提前致谢

【问题讨论】:

第一个问题是你为什么要使用两个不同的上下文? 正如在 CoreDataBooks SDK 示例中所做的那样,我正在使用另一个上下文在商店中添加新实体。 在这种情况下,请忘记单独的上下文,如果您只是创建不同实体的新实例,则没有理由使用单独的上下文。您通常会在多线程环境中查看单独的托管对象上下文(还有其他原因,但这是最常见的原因) 【参考方案1】:

您需要在同一托管上下文中加载两个实体以创建任何类型的关系(尽管我猜您已经弄清楚了!)。

你有一个来自第一个托管对象上下文的 Foo - 称之为 Foo1。

Foo *foo1 = your initial Foo;

// Get a foo from the new managed context
NSManagedObjectID fooID = [foo1 managedObjectID];
Foo *foo2 = [addingManagedObjectContext objectWithID:fooID];

您现在可以使用 Foo2 来创建关系

【讨论】:

以上是关于Core Data - 如何在不同的上下文中建立两个对象之间的关系的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Core Data 中存储一组自定义(和重复)对象?

如何在Core Data中同步两个独立的NSManagedObjectContext?

Core-Data:如何在一个关系中保存一个对象两次

在基于导航的应用程序中使用 Core Data 时,我如何(应该?)在 UITableViews 之间传递上下文?

如何确保从上下文而不是缓存中获取 Core Data Fetched Property?

Core Data 托管对象上下文线程同步