在主线程中添加的线程中读取数据的核心数据

Posted

技术标签:

【中文标题】在主线程中添加的线程中读取数据的核心数据【英文标题】:Core Data Reading Data in Thread that's added in the Main Thread 【发布时间】:2012-09-12 19:58:02 【问题描述】:

我有一个基于 Mac 文档的应用程序,使用 NSPersistentDocument 作为文档模型。

创建新文档时,应用会在 initiWithType 方法中将一些默认数据(一些运动对象和用户数据)添加到文档中。

- (id)initWithType:(NSString *)typeName error:(NSError **)outError 
self = [super initWithType:typeName error:outError];

NSManagedObjectContext *managedObjectContext = [self managedObjectContext];

[[SportManagement sharedManager] addDefaultSports:managedObjectContext];
[[UserManagement sharedManager] addDefaultUser:managedObjectContext];

[managedObjectContext processPendingChanges];

return self;

该应用程序有一个导入功能,可以从某些硬件中导入数据,它在一个线程中运行,我设置如下(managedObjectContext 是 NSPersistentDocument 的):

dispatch_async(dispatch_get_global_queue(0, 0), ^ 

    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
    [moc setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]];

数据从硬件导入到许多 NSManagedDataObject 项中。每个 ManagedObject 都有一个“Sport”字段,需要用创建文档时创建的运动对象之一填充该字段。

但是,- (id)initWithType:(NSString *)typeName error:(NSError **)outError 中添加的所有运动对象都不存在于线程 (moc) 中的新 ManagedObjectContext 中。

如果我运行应用程序,创建一个新文档,然后让应用程序闲置一分钟左右,然后尝试导入,那么 Sport 对象确实存在于线程托管对象上下文中。

如何将线程中的新 ManagedObjectContext 与 NSPersistantDocument 中的主线程同步?

我试过:[managedObjectContext processPendingChanges];[managedObjectContext setStalenessInterval];,但似乎都不能解决这个问题。

有趣的是,这似乎不会在 Mac OS X 10.8 中发生,仅在 10.7 中发生

【问题讨论】:

【参考方案1】:

设置您的“主” MOC 以接收NSManagedObjectContextDidSaveNotification 通知,并在后台 MOC 保存时将更改与-mergeChangesFromContextDidSaveNotification: 合并。

编辑

好的,看起来您已经在 MOC 中进行了更改,但它只是一个暂存器。在数据真正保存到持久存储之前,持久存储不知道新数据的变化。

因此,当您创建另一个 MOC 并将其连接到 PSC 时,它不知道这些更改。

您可以知道自动保存何时启动,因为“过一段时间”它会起作用。

在您创建初始内容后,我会尝试手动保存文档。

【讨论】:

我已经在应用程序中得到了它,但这是为了将线程中添加的数据返回到主线程中。我要做的是获取已经添加到主线程中的文档 ManagedObjectContext 的数据,以显示在新线程的新 ManagedObjectContext 中。 那我就糊涂了,因为现在,当我把你的问题和评论放在一起时,我什至无法想象你描述的场景。即,评论中的最后一句话是什么意思?您能否详细说明(并且可能使用导致问题的实际代码)? 我已经编辑了原件 - 希望现在更清楚了 - 感谢您的帮助。 啊,对了——现在清楚多了。所以我需要在导入之前强制自动保存我的文档。谢谢你的帮助。

以上是关于在主线程中添加的线程中读取数据的核心数据的主要内容,如果未能解决你的问题,请参考以下文章

后台核心数据

核心数据使用完成处理程序执行获取请求或在主线程以外的其他线程中执行

在同一个后台线程上运行 FMDB 进程?

核心数据多线程[关闭]

核心数据:获取背景并在主线程上使用 objectWithID,性能优势?

JAVA开启三个线程,去读取数组中的数据不能重复