2012-05-30 50 views
0

我有一个问题,我只是简单地不能找出解决。麻烦,更改不会写入正确

配置为使用核心数据我的应用程序(由Xcode中创造的AppDelegate的templatecode),进口了大量的数据在后台线程。问题是我在UI线程中对Core Data所做的所有更改都未保存到存储(有时),如果我已经运行了大量导入。所有的数据保存正确,如果我不运行导入,并且问题不一致,它是一个开/关的问题,但我已经跟踪它是导致问题的导入。

我的线程代码如下所示(简化)

-(void)startSynchronization{ 
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(startSync:) object:nil]; 
[self.thread start]; 
} 


-(void)startSync{ 
NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc] init]; 
[importContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 
[importContext setUndoManager:nil]; 
... import a lot of code and create thousands of core data entities.. 

} 

的persistentStoreCoordinator(从现在起,PSC)是从应用程序的AppDelegate中的PSC,我认为这是问题。我读过多个线程应该使用单独的PSC,但我如何创建一个PSC并将其与AppDelegate模板代码中创建的核心数据文件一起分配?

导入后核心数据的读取工作正常,但是当我稍后在核心数据模型中标记我的“文档”实体中的一个作为我的最爱时,即使将此更改写入数据库我从AppDelegate调用保存在我的上下文中。

我认为全球PSC来同步多个上下文,在我的应用程序一个上下文,并在线程导入代码导入方面?

我怎样才能确保进口代码和UI代码看到相同的变化,我的店是一致的?

谢谢

/雅各布

回答

3

他们修补多线程的方式在iOS 5中/ MacOS的10.7合作。现在,有三种模式对多线程的核心数据:NSConfinementConcurrencyTypeNSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType。第一个是过去的工作方式,这是你正在使用的。我提到其他人,因为他们可能值得研究,并且因为这些术语在搜索时可能很有用。

对于线约束法,创建每个线程一个新的管理对象方面,正如你在干什么。我认为在你的循环之后你会在背景上调用save。您错过的步骤是回应NSManagedObjectContextDidSaveNotification。来自Apple的documentation

通常,在线程A上注册受管对象上下文保存通知NSManagedObjectContextDidSaveNotification。当您收到通知时,其用户信息字典将包含带有在线程B上插入,删除和更新的托管对象的数组。但是,由于托管对象与不同的线程关联,因此不应直接访问它们。相反,您将通知作为参数传递给mergeChangesFromContextDidSaveNotification:(您发送到线程A上的上下文)。使用此方法,上下文能够安全地合并更改。

综上所述,你做的是订阅的通知,如果它发生(与您选择的叫法),你只需拨打mergeChangesFromContextDidSaveNotification:在你的主线程的管理对象上下文,传递通知对象后一种方法,像这样:

- (void)mergeChanges:(NSNotification *)notification 
{ 
    if (notification.object != self.context) { 
     [self.context mergeChangesFromContextDidSaveNotification:notification]; 
    } 

    return; 
} 

假设你已经订阅了通知,并self.context指的是你的主线程的管理对象上下文。这应该处理获取更新。

我之前提到的其他并发类型的原因是另一种做并发的方法(如果您使用的是最新的操作系统)涉及父和子上下文。您可以使用专用队列模式操作上下文,并将其父级设置为您的主要MOC。当上下文有父项时,对子上下文的保存操作只是将其更改推送给父项,而不触及磁盘。这可能是您可以研究的另一种模式。

+0

非常感谢:)我实际上在前段时间阅读过有关ContectDidSaveNotification的内容,但我忘了所有关于它的内容,也许我当时不太明白它:(愚蠢的我..我没有实现合并模式,现在都好了:) –

+0

@JacobRungwald如果这是正确的答案,你应该让艾米的问题正确(答案旁边的复选框)。然后你们都获得声望点。 – Tim