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

时间:2015-11-19 11:56:05

标签: ios objective-c multithreading core-data

我有一个应用程序,我正在使用Core Data。这是我第一次使用它,所以我使用了Apple在Resource.language.resx中提供的相同Core Data堆栈。

我面临的问题描述如下: 我有一个名为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.
}

注意A通过一对多关系与B相关,即A包含B的+(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; } 。 如图所示,这两个调用需要相当长的时间才能完成并冻结UI。我不希望它发生,因此我创建了一个序列NSSet并使用dispatch_queue在其上调用了firstSaver

问题是,由于dipatch_async的实例已在主线程上创建,如果我在NSManagedObjectContext内访问它,则会产生dispatch_async

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

2 个答案:

答案 0 :(得分:4)

您应创建要使用的新子管理对象上下文,其中包含专用队列类型,主要上下文作为父项。你的所有逻辑都应该在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

答案 1 :(得分:-1)

使用Coredata进行多线程处理是一种痛苦。你应该尽可能避免这种情况。如果创建或修改MO需要很长时间,请在后台线程中创建数据或修改现有数据,然后对所有Coredata操作执行performSelectorOnMainthread。