不久前我根本没有意识到多线程coredata直到mac雪豹系统出来那天。但是随着iOS5中上下文context层次的出现和block使用的流行,多线程coredata变得触手可及。
当我就职于Resonate时,我发现有一些项目应用是用多线程写的,期间通过了大量的试错和崩溃。下面我将把这些分享出来让你们不再犯同样的错误。
尽管我使用了多线程这个单词,但是可能的是你不需要直接的去处理使用线程。使用操作队列对你大部分的处理机制是一种比较好的方法。把你的算法做一个简单的封装,然后放到NSOperationQueue中去管理他们。还有不要直接创建NSThread实例除非你有足够的理由为什么要这样做。
在Coredata中使用UIManagedDocument:
确实,当你等着在iOS5中使用Coredata时,你可能会想要用UIManagedDocument,至少用这个类来管理你的Coredata栈,现在就是,你可以用它来管理你的Coredata实例NSManagedObjectContext, NSPersistentStoreCoordinator或者其他部分。
甚至如果你需要共享Coredata类给你的MacAPP,你也可以将你的实体类分隔开并且在两个不同的平台上云运行。如果你觉得UIManagedDocument不够好,那么请给出你的理由。
当你使用UIManagedDocument的时候,你会得到一系列的相关联的NSManagedObjectContext实例。用一个main context作为GUI界面对象,用一个root context作为main context的parent,用来异步的存储数据到persistent storage(数据库)中。当正在处理数据的context被创建时你不应该直接去保存他们,而是要绕过undo和很多其他底层的东西。UIManagedDocument可以为你周期性的用正确的顺序自动保存他们。
使用上下级结构的context来管理对象:
从构建这个模块开始,我进一步建议使用新的context层次结构,这在iOS中确实能够很好的提高效率。
·使用root context来存储从网络获取的数据
·使用main context来为界面GUI组件和其他需要在主线程操作的对象
·为需要后台处理数据的任务创建单独的工作context作为main context的children context
你可以看看下图的模式,很明显的阐述了用户在 View controller通过一系列动作刷新界面的过程。如果你用 ASIHTTPRequest来请求网络的话,可以采用异步逻辑。当请求完成时,你可以把原始数据放到一个操作队列里去解析他(这里使用 +[ASIHTTPRequest sharedQueue]会非常方便),当解析完数据之后,在使用 root context的私有队列去更新数据到数据管理对象中。在更新数据之后,将所有更新的数据对象的 IDs返回到主线程给你的 View controller去更新界面,注意这里不能在两个线程之间传递实际的数据管理对象( managed object instances),因为这样会造成很严重的问题。
在任务线程队列里使用多个子 context
·新的 NSManagedObjectContext架构(上下级的 context)