核心数据多线程应用程序

Slo*_*ree 62 iphone multithreading core-data ios

我正在尝试以多线程方式使用核心数据.我只是想在后台下载新数据时显示以前下载的数据的应用程序.这应该让用户在更新过程中访问应用程序.

我有一个NSURLConnection使用委托异步下载文件(并显示进度),然后我使用XMLParser解析新数据并在单独的上下文中创建新的NSManagedObjects,具有自己的persistentStore并使用单独的线程.

问题是在显示新对象时在旧对象的同一上下文中创建新对象会抛出BAD_INSTRUCTION异常.所以,我决定为新数据使用单独的上下文,但是我无法找到一种方法,一旦完成就将所有对象移动到其他上下文.

Paolo又名SlowTree

Yuj*_*uji 151

带有Core Data文档的Apple Concurrency是开始的地方.仔细阅读它...我被误解了很多次!

基本规则是:

  1. NSPersistentStoreCoordinator每个程序使用一个.每个线程你不需要它们.
  2. NSManagedObjectContext每个线程创建一个.
  3. 永远不要将NSManagedObject线程传递给另一个线程.
  4. 而是通过获取对象ID -objectID并将其传递给另一个线程.

更多规则:

  1. 确保在获取对象ID之前将对象保存到存储中.在保存之前,它们是临时的,您无法从另一个线程访问它们.
  2. 如果您从多个线程更改托管对象,请注意合并策略.
  3. NSManagedObjectContext-mergeChangesFromContextDidSaveNotification:是有帮助的.

但让我再说一遍,请仔细阅读文件!这真的很值得!

  • 此文档尚未更新,以利用iOS 5中非常重要的改进 - 我在答案中链接到的视频现在是一个更好的参考. (2认同)
  • @JoãoNunes遗憾的是,您无法可靠地读取另一个线程上的对象 - 它有时可能会起作用,但如果您导致出现故障对象,则会调用(最多)未定义的行为. (2认同)
  • 遗憾的是,关于核心数据并发的核心数据编程指南部分已严重过时.它描述了线程限制,这已经过时(并且已经使用了好几年). (2认同)

Jos*_*phH 76

目前[2015年5月] 带有核心数据Apple Concurrency文档充其量是非常误导性的,因为它没有涵盖iOS 5中的任何增强功能,因此不再显示同时使用核心数据的最佳方法.iOS 5中有两个非常重要的变化 - 父上下文和新的并发/线程类型.

我还没有找到任何全面涵盖这些新功能的书面文档,但WWDC 2012视频"会话214 - 核心数据最佳实践"确实解释了这一切.

Magical Record使用这些新功能,值得一看.

真正的基础仍然是相同的 - 您仍然只能使用托管对象创建其托管对象上下文的线程.

您现在可以使用[moc performBlock:]在正确的线程上运行代码.

没有必要再使用mergeChangesFromContextDidSaveNotification:而是创建一个子上下文来进行更改,然后保存子上下文.保存子上下文将自动将更改推送到父上下文,并将更改保存到磁盘,只需在其主题上执行父上下文的保存.

为此,您必须使用并发类型创建父上下文,例如:

mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
Run Code Online (Sandbox Code Playgroud)

然后在后台线程:

context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[context setParentContext:mainManagedObjectContext];

<... perform actions on context ...>

NSError *error;
if (![context save:&error])
{
    <... handle error ...>
}
[mainManagedObjectContext performBlock:^{
    NSError *e = nil;
    if (![mainContext save:&e])
    {
        <... handle error ...>
    }
}];
Run Code Online (Sandbox Code Playgroud)

  • Upvote获取最新信息.SO应该实施机制来促进新技术开发所涉及的答案,并淡化那些过时的已接受答案.感谢您推荐Magic Record框架.它的文档看起来非常好.我可能稍后再试一次. (7认同)
  • 谢谢,已经纠正了WWDC链接.我没有使用UIManagedDocument,但在私有线程上拥有最多上下文是一种常见模式,因此保存操作不会阻止ui - 如果要更新大量数据,操作可能需要一段时间. (2认同)