Ios 使用NSThread和core数据时出现问题,更改未正确写入
我有一个问题,我就是想不出解决办法 我的应用程序配置为使用核心数据(使用xCode创建的AppDelegate中的templatecode),在后台线程中导入大量数据。问题是,如果我运行了大型导入,我在UI线程中对核心数据所做的所有更改(有时)都不会保存到存储中。如果我没有运行导入,并且问题不一致,所有数据都会正确保存,这是一个开/关问题,但我已经跟踪到导致问题的导入 我的线程代码如下所示(简化) persistentStoreCoordinator(从现在开始的PSC)是来自应用程序AppDelegate的PSC,我认为这就是问题所在。我了解到多线程应该使用单独的PSC,但是如何创建PSC并将其与AppDelegate模板代码中创建的核心数据文件一起分配 导入后核心数据的读取工作正常,但当我稍后将核心数据模型中的一个“文档”实体标记为我的最爱时,即使我从AppDelegate调用save on my context,此更改也不会写入数据库 我认为全局PSC用于同步多个上下文,我的应用程序中的一个上下文,线程导入代码中的导入上下文 如何确保导入代码和UI代码看到相同的更改,以及我的存储一致 多谢各位Ios 使用NSThread和core数据时出现问题,更改未正确写入,ios,core-data,Ios,Core Data,我有一个问题,我就是想不出解决办法 我的应用程序配置为使用核心数据(使用xCode创建的AppDelegate中的templatecode),在后台线程中导入大量数据。问题是,如果我运行了大型导入,我在UI线程中对核心数据所做的所有更改(有时)都不会保存到存储中。如果我没有运行导入,并且问题不一致,所有数据都会正确保存,这是一个开/关问题,但我已经跟踪到导致问题的导入 我的线程代码如下所示(简化) persistentStoreCoordinator(从现在开始的PSC)是来自应用程序AppDe
/Jacob他们改进了iOS 5/MacOS 10.7中多线程的工作方式。现在,多线程核心数据有三种模式:
NSConfinementConcurrencyType
、NSPrivateQueueConcurrencyType
和NSMainQueueConcurrencyType
。第一个是过去的工作方式,也是你正在使用的方式。我之所以提到其他的,是因为它们可能值得研究,也因为这些术语在搜索时可能很有用
对于线程限制方法,您可以像现在这样为每个线程创建一个新的托管对象上下文。我认为在循环之后,您正在后台上下文中调用save
。您缺少的步骤是响应NSManagedObjectContextDidSaveNotification
。来自苹果的:
通常,在线程A上注册托管对象上下文保存通知,NSManagedObjectContextDidSaveNotification
。当您收到通知时,其用户信息字典包含在线程B上插入、删除和更新的托管对象的数组。但是,由于托管对象与不同的线程关联,因此您不应直接访问它们。相反,您将通知作为参数传递给mergeChangesFromContextDidSaveNotification:
(发送到线程A上的上下文)。使用此方法,上下文能够安全地合并更改
总之,您要做的是订阅该通知,当它发生时(并且调用了选择器),您只需在主线程的托管对象上下文上调用mergeChangesFromContextDidSaveNotification:
,将通知对象传递给后一种方法,如下所示:
- (void)mergeChanges:(NSNotification *)notification
{
if (notification.object != self.context) {
[self.context mergeChangesFromContextDidSaveNotification:notification];
}
return;
}
假设您已经订阅了通知,self.context
引用了主线程的托管对象上下文。这应该可以处理更新
我在上面提到其他并发类型的原因是,执行并发的另一种方法(如果您使用的是最新的操作系统)涉及父上下文和子上下文。您可以让一个上下文在私有队列模式下运行,并将其父级设置为您的主MOC。当上下文有父上下文时,子上下文上的保存操作只将其更改推送到父上下文,而不接触磁盘。这可能是您可以研究的另一种模式。他们改进了iOS 5/MacOS 10.7中多线程的工作方式。现在,多线程核心数据有三种模式:
NSConfinementConcurrencyType
、NSPrivateQueueConcurrencyType
和NSMainQueueConcurrencyType
。第一个是过去的工作方式,也是你正在使用的方式。我之所以提到其他的,是因为它们可能值得研究,也因为这些术语在搜索时可能很有用
对于线程限制方法,您可以像现在这样为每个线程创建一个新的托管对象上下文。我认为在循环之后,您正在后台上下文中调用save
。您缺少的步骤是响应NSManagedObjectContextDidSaveNotification
。来自苹果的:
通常,在线程A上注册托管对象上下文保存通知,NSManagedObjectContextDidSaveNotification
。当您收到通知时,其用户信息字典包含在线程B上插入、删除和更新的托管对象的数组。但是,由于托管对象与不同的线程关联,因此您不应直接访问它们。相反,您将通知作为参数传递给mergeChangesFromContextDidSaveNotification:
(发送到线程A上的上下文)。使用此方法,上下文能够安全地合并更改
总之,您要做的是订阅该通知,当它发生时(并且调用了选择器),您只需在主线程的托管对象上下文上调用mergeChangesFromContextDidSaveNotification:
,将通知对象传递给后一种方法,如下所示:
- (void)mergeChanges:(NSNotification *)notification
{
if (notification.object != self.context) {
[self.context mergeChangesFromContextDidSaveNotification:notification];
}
return;
}
假设您已经订阅了通知,self.context
引用了主线程的托管对象上下文。这应该可以处理更新
我在上面提到其他并发类型的原因是另一种并发方法(如果您使用的是最新的操作系统)涉及paren