我可以在并发GCD队列中使用NSManagedObjectContext和NSPrivateQueueConcurrencyType

时间:2013-10-24 07:47:49

标签: core-data nsmanagedobjectcontext

到目前为止我的方法是这样的:

  • 1-初始化的主要上下文如下:

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];
    if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        DDLogModel(@"Unresolved error %@", error.localizedDescription);
        return;
    }
    
    self.context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    self.context.persistentStoreCoordinator =_persistentStoreCoordinator;
    
  • 2-然后,当我开始创建核心数据对象或同时修改它们的关系时:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSManagedObjectContext *tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
    tempContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
    
    //  Do stuff
    
    [tempContext save:nil];
    });
    
  • 3-最后,主要上下文通过NSManagedObjectContextDidSaveNotification

  • 进行合并

但是,我最近看到了一种不同的方法,对于第2步,他们改为使用NSPrivateQueueConcurrencyType创建一个上下文,使其成为主要上下文的子项,并通过{{1}进行任何工作}

默认情况下,这最后一种方法是并发的(即使没有明确地将其分配)?或者与我解释的方法相比有什么优势?

让我失望的另一件事是,尽管上下文具有-performBlock:parentContext属性,但设置后者似乎意味着无法设置前者。也就是说,具有持久性存储协调器的上下文实际上将该存储协调器作为其父上下文?

更新 另一个有趣的事情是,使用我上面描述的方法(使用GCD),Everynow然后当我做persistentStoreCoordinator时,我得到一个奇怪的行为:没有返回错误(假设我传入一个NSError对象,不像例如),但如果我设置了通用的Objective-C异常指针,那么后台线程就会停在那里,好像有一个异常。但是,如果我继续该应用程序不会崩溃并继续前进,主要的moc似乎很好。

1 个答案:

答案 0 :(得分:0)

你是对的。 performBlock将自动在后台执行工作。在某些情况下,使用当前线程(主要或背景)可能是有意义的,在这种情况下,您可以使用performBlockAndWait。建议使用子上下文。

我想你的设置也可以正常工作。我想使用子上下文的优点在于更加结构化的保存方法,即将“推送”保存到父上下文中。只有父上下文才会实际触及持久存储,因此在线程安全方面更好。

您的上一个问题尚不清楚。上下文只能将上下文作为其父上下文,而不是持久性存储协调器。然而,令人困惑的是,在iOS 5之前只有一个“父存储”,并且通过引入子上下文,它可以被替换可选地由父上下文。阅读所有相关内容here