1

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

  • 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,使其成为主上下文的子上下文,并通过-performBlock:

默认情况下,最后一种方法是并发的吗(即使没有明确地调度它)?或者比我解释的方法有什么优势?

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

更新: 另一个有趣的事情是,使用我上面描述的方法(使用 GCD),时不时地[tempContext save:]我会得到一个奇怪的行为:没有返回错误(假设我确实传入了一个 NSError 对象,与示例不同),但是如果我将通用的 Objective-C 异常指针设置为 on,后台线程确实会停在那里,就好像有异常一样。但是,如果我继续,应用程序不会崩溃并继续运行,主 moc 似乎还不错。

4

1 回答 1

0

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

我想您的设置也可以正常工作。我想使用子上下文的优势在于更结构化的保存方法,即“向上推”保存到父上下文中。只有父上下文才会真正接触持久存储,所以这在线程安全方面更好。

你的最后一个问题不清楚。一个上下文只能有一个上下文作为其父上下文,而不是一个持久存储协调器。但是,您可能会感到困惑的是,在 iOS 5 之前只有一个“父存储”,并且随着子上下文的引入,它可以可选地被父上下文替换在这里阅读所有相关信息。

于 2013-10-24T08:18:03.533 回答