核心数据单独的托管对象上下文共享相同的持久存储没有看到更改

时间:2012-09-08 10:54:17

标签: objective-c ios core-data

我今天发现的事情让我感到困惑。

我认为只要所有上下文都使用相同的Core Data持久性存储,一个上下文中的任何更改都应该在保存上下文后出现在另一个上下文中。

E.g。在视图控制器A中,我有1个上下文(上下文A),在视图控制器B中,我有另一个上下文(上下文B)。现在,上下文A和上下文B都指向同一个持久存储。

在上下文A中,我从持久性存储中获取了一个托管对象,更新了托管对象的属性,然后使用managedObjectContext保存操作将更改保存回持久性存储。

现在我打开第二个视图控制器并从同一个持久性存储执行获取请求,但是我的第二个视图控制器没有看到更新的属性更改,直到我重新启动模拟器。

真正奇怪的是,如果这是我第一次将新的托管对象插入持久性存储,控制器B将看到更改,但后续更改不会显示。

我已经在长时间的战斗中修复了这个问题,我只是想知道为什么有两个单独的上下文(当然都在主线程上)共享同一个持久存储在模拟器重启之前看不到更改。

对于那些想要知道我如何修复它的人,在我的基本视图控制器中,控制器A和B都继承自,而不是alloc-initing一个新的上下文(因此控制器A和B有两个独立的上下文),我告诉基本视图控制器引用app委托中的上下文(因此,控制器A和B现在指向相同的上下文)。

以下是解释我所看到的内容的图表:

enter image description here

在第二个视图控制器中获取的结果值是旧值。

如果我将一些数据提交到持久性存储,只要我从同一个持久性存储中获取,它就应该永久存在并且可以访问,除非我误解了managedObjectContext保存:实际上并没有对持久性存储进行更改直到应用结果。

1 个答案:

答案 0 :(得分:1)

张,

没有细节,很难弄清楚问题。

一个简单的建议是验证您是否合并了应用中两个不同上下文之间的更改。换句话说,您需要验证主要上下文合并来自另一个的更改。这可以简单地实现如下。

注册此通知,例如,在AppDelegate或您正在创建核心数据堆栈。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil];

实现contextChanged:方法以合并更改。

- (void)contextChanged:(NSNotification*)notification
{
    if ([notification object] == [self managedObjectContext])
        return;

    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES];
        return;
    }

    [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}

有关详细信息,请参阅Marcus Zarra tutorial

此外,如果将表与NSFetchedResultsController结合使用,请记住实现委托的方法。有关信息,请参阅NSFetchedResultsControllerDelegate class。

希望有所帮助。