NSManagedObjectController 不合并从添加管理对象上下文的更改

Posted

技术标签:

【中文标题】NSManagedObjectController 不合并从添加管理对象上下文的更改【英文标题】:NSManagedObjectController not merging in changes from addingManagedObjectContext 【发布时间】:2011-05-12 19:37:42 【问题描述】:

我正在尝试通过使用带有 CoreData 的 NSFetchedResultsController 调用 mergeChangesFromContextDidSaveNotification 将addingManagedObjectContext 中的更改合并到我的主managedObjectContext 中。像这样:

- (void)addGoalViewController:(AddGoalViewController *)controller didFinishWithSave:(BOOL)save 
    if (save) 
        NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
        [dnc addObserver:self
                selector:@selector(addControllerContextDidSave:)
                    name:NSManagedObjectContextDidSaveNotification
                  object:addingManagedObjectContext];

        NSLog(@"Before save - addingManagedObjectContext - Number of registered objects: %d", [[addingManagedObjectContext registeredObjects] count]);
        NSLog(@"Before save - addingManagedObjectContext - Number of inserted objects: %d", [[addingManagedObjectContext insertedObjects] count]);
        NSLog(@"Before save - addingManagedObjectContext - Number of updated objects: %d", [[addingManagedObjectContext updatedObjects] count]);
        NSLog(@"Before save - addingManagedObjectContext - Number of deleted objects: %d", [[addingManagedObjectContext deletedObjects] count]);

        // Save the new object to the adding managed object context
        NSError *error = nil;
        if ([addingManagedObjectContext hasChanges] && [addingManagedObjectContext save:&error] == NO) 
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        

        NSLog(@"After save - addingManagedObjectContext - Number of registered objects: %d", [[addingManagedObjectContext registeredObjects] count]);
        NSLog(@"After save - addingManagedObjectContext - Number of inserted objects: %d", [[addingManagedObjectContext insertedObjects] count]);
        NSLog(@"After save - addingManagedObjectContext - Number of updated objects: %d", [[addingManagedObjectContext updatedObjects] count]);
        NSLog(@"After save - addingManagedObjectContext - Number of deleted objects: %d", [[addingManagedObjectContext deletedObjects] count]);

        // Remove the adding context observer
        [dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];
    
    // Reset the adding context back to its default state
    [addingManagedObjectContext reset];

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

    // Dismiss the add goal view to return to the main list
    [self dismissModalViewControllerAnimated:YES];

我正在关注 CoreDataBooks 示例当我尝试合并更改时,虽然它不起作用。这是我的合并代码:

- (void)addControllerContextDidSave:(NSNotification *)saveNotification 
    NSManagedObjectContext* context = [fetchedResultsController managedObjectContext];
    // Merging changes causes the fetched results controller to update its results
    NSLog(@"Before merge - managedObjectContext - Number of registered objects: %d", [[context registeredObjects] count]);
    NSLog(@"Before merge - managedObjectContext - Number of inserted objects: %d", [[context insertedObjects] count]);
    NSLog(@"Before merge - managedObjectContext - Number of updated objects: %d", [[context updatedObjects] count]);
    NSLog(@"Before merge - managedObjectContext - Number of deleted objects: %d", [[context deletedObjects] count]);
    [context mergeChangesFromContextDidSaveNotification:saveNotification];
    NSLog(@"After merge - managedObjectContext - Number of registered objects: %d", [[context registeredObjects] count]);
    NSLog(@"After merge - managedObjectContext - Number of inserted objects: %d", [[context insertedObjects] count]);
    NSLog(@"After merge - managedObjectContext - Number of updated objects: %d", [[context updatedObjects] count]);
    NSLog(@"After merge - managedObjectContext - Number of deleted objects: %d", [[context deletedObjects] count]);

不幸的是,它似乎没有将对象添加到我的主要托管对象上下文中,它添加到了我的添加管理对象上下文中,但在合并之后它应该将它们合并到主要托管对象上下文中。但是,我的主托管对象上下文中的注册对象数量仍然为0。保存后看到addingManagedObjectContext中的1个注册对象了吗?那应该在我的主要 managedObjectContext 中,因为我合并了它,但事实并非如此。它反而粘在我的addingManagedObjectContext 中。

我查看了 Apple 类参考文档,从我读到的内容看来,

Before save - addingManagedObjectContext - Number of registered objects: 1
Before save - addingManagedObjectContext - Number of inserted objects: 1
Before save - addingManagedObjectContext - Number of updated objects: 1
Before save - addingManagedObjectContext - Number of deleted objects: 0
Before merge - managedObjectContext - Number of registered objects: 0
Before merge - managedObjectContext - Number of inserted objects: 0
Before merge - managedObjectContext - Number of updated objects: 0
Before merge - managedObjectContext - Number of deleted objects: 0
After merge - managedObjectContext - Number of registered objects: 0
After merge - managedObjectContext - Number of inserted objects: 0
After merge - managedObjectContext - Number of updated objects: 0
After merge - managedObjectContext - Number of deleted objects: 0
After save - addingManagedObjectContext - Number of registered objects: 1
After save - addingManagedObjectContext - Number of inserted objects: 0
After save - addingManagedObjectContext - Number of updated objects: 0
After save - addingManagedObjectContext - Number of deleted objects: 0

从这个输出可以看出,它正在将对象添加到addingManagedObjectContext,但它没有将对象合并到主managedObjectContext。相反,该对象保留在addingManagedObjectContext 中。从 Apple Class Reference 看来,这似乎不应该发生。相反,它应该将对象合并到 managedObjectContext 中。而且似乎没有任何方法可以检查 mergeChangesFromContextDidSaveNotification 是否错误。

【问题讨论】:

【参考方案1】:

据我了解,NSFetchedResultsController 应该自动更新和合并上下文中的数据。如果在保存第二个上下文之前,您的对象位于 Fetched Result Controller 的上下文中,则它应该监视这些更新。您可以通过在控制器上设置委托并实现方法来自己检查:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

根据 Apple 的文档:

通知接收器,由于添加、删除、移动或更新,获取的结果控制器已完成一个或多个更改的处理。

更多详情:NSFetchedResultsControllerDelegate

【讨论】:

NSFetchedResultsController 不会为我自动更新和合并数据。即使是这样,我也会明确告诉它保存未保存的更改,但它仍然不起作用。我确信这是我的错,但我认为写一个好的 Objective-C 问题几乎是不可能的,因为语言太冗长了。

以上是关于NSManagedObjectController 不合并从添加管理对象上下文的更改的主要内容,如果未能解决你的问题,请参考以下文章