如何在多个线程上处理 NSManagedObjectContext 和 NSManagedObject 创建和编辑?

Posted

技术标签:

【中文标题】如何在多个线程上处理 NSManagedObjectContext 和 NSManagedObject 创建和编辑?【英文标题】:How to handle NSManagedObjectContext and NSManagedObject creation and editing on multiple threads? 【发布时间】:2015-11-19 11:56:05 【问题描述】:

我有一个使用 Core Data 的应用程序。这是我第一次使用它,所以我使用的是 Apple 在 AppDelegate.m 中提供的相同核心数据堆栈。

我面临的问题描述如下: 我有一个名为firstSaver 的方法,它执行以下操作:

+(void) firstSaver  
    // 1) get some values from system
    // 2) do some processing on those values ( This takes considerable time)
    // 3) create a NSManagedObject instance of entity A ,say mObj ,by filling in the processed  values. I create multiple objects. In this step, I use the main managedObjectContext that is provided by the        AppDelegate to me. 
    // 4) pass this NSManagedObject to secondSaver like : 
        [self secondSaver : mObj];
    // 5) save the managedObjectContext.

第二种方法是:

+(void) secondSaver : (NSManagedObject *)someObj  

    // 1) again fetch some values, this too takes considerable time.
    // 2) create a NSManagedObject which is instance of entity B, fill the processed values, attach this instance to the someObj instance.
    return;

请注意,A 与 B 是一对多的关系,即 A 包含 B 的 NSSet。 如图所示,这两个调用需要相当长的时间才能完成,并且会冻结 UI。我不希望它发生,因此我创建了一个序列号dispatch_queue,并使用dipatch_async 在其上调用了firstSaver

问题是NSManagedObjectContext 的实例是在主线程上创建的,如果我在dispatch_async 中访问它,它会导致EXEC_BAD_ACCESS

处理这种情况并使用适当的托管对象上下文来处理多线程的正确方法可能是什么?任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

您应该创建新的子托管对象上下文以使用,私有队列类型和主上下文作为父级。您的所有逻辑都应该在 performBlockAndWait: 中,您可以在那里进行长查询并创建新对象。

要在此处使用mObj,您需要获取其objectID,然后使用existingObjectWithID:error: 在子上下文中获取适当的版本。然后,您可以在正确的上下文中将新对象连接到现有对象。

完成后,保存子上下文,然后在主上下文上使用 performBlock 并保存它。

// move to background thread
// create child
// set parent
// perform block and wait on new context
  // find the existing object for mObj ID
  // search, create, associate
  // save
  // perform block on the main context
    // save

【讨论】:

【参考方案2】:

使用 Coredata 进行多线程处理是一件令人头疼的事情。如果可能,您应该避免这种情况。如果 MO 的创建或修改需要很长时间,请在后台线程中创建数据或修改现有的数据,然后为所有 Coredata 操作执行 performSelectorOnMainthread。

【讨论】:

以上是关于如何在多个线程上处理 NSManagedObjectContext 和 NSManagedObject 创建和编辑?的主要内容,如果未能解决你的问题,请参考以下文章

java能利用多核cpu吗

如何防止方法跨多个线程运行?

单核CPU如何执行多线程

java多线程

线程知识点

线程知识点