在后台线程上保存到核心数据上下文中

时间:2013-09-15 12:00:16

标签: ios objective-c multithreading core-data

我正在努力解决这个问题已经有一段时间了,Apple的文档和SO到目前为止并没有帮助。我在UIManagedDocument上使用ManagedObjectContext,下面的代码运行正常。然后我决定在AppDelegate中使用Apple的CoreData模板,因此在AppDelegate中创建了模型,持久性存储协调器和上下文。使用AppDelegate的上下文获取是没有问题的,但是后台保存是一个问题。我应该在我保存的线程上有本地上下文,并且根据Apple有相同的持久性存储协调器。但是下面的代码实际上并没有保存数据。请问有人可以提供建议吗?谢谢。

- (void)fetchAndPersist
{
    dispatch_queue_t ffetchQ = dispatch_queue_create("ForFetch", NULL);
    dispatch_async(ffetchQ, ^{

        NSManagedObjectContext *secureManagedObjectContext;
        NSPersistentStoreCoordinator *coordinator = [appDelegate persistentStoreCoordinator];
        if (coordinator != nil) {
            secureManagedObjectContext = [[NSManagedObjectContext alloc] init];
            [secureManagedObjectContext setPersistentStoreCoordinator:coordinator];
        }

        // find missing date
        DataManager *dataManager = [[DataManager alloc] init];
        NSDate *missingDate = [dataManager findMissingDateFromDate:selectedDate inContext:secureManagedObjectContext];

        if (missingDate) {
            // fetch and parse data
            DataFetcher *dataFetcher = [[dataFetcher alloc] init];
            NSDictionary *fetchResponse = [dataFetcher parseDataForDate:missingDate];

            // persist it in a block and wait for it
            [secureManagedObjectContext performBlock:^{
                DataStore *dataStore = [[DataStore alloc] init];
                BOOL parsingError = [dataStore persistData:fetchResponse inContext:secureManagedObjectContext];

                if (parsingError) {
                    // handle error
                } else {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        // perform on main
                        [self fetchAndPersist];
                    });
                }
            }];
        }
    });
}

2 个答案:

答案 0 :(得分:18)

尝试使用父/子上下文:

http://www.cocoanetics.com/2012/07/multi-context-coredata/

在上面的链接中,您可以找到代码示例。

答案 1 :(得分:3)

发生崩溃是因为NSManagedObjectContext使用的是较早的obsolete thread confinement model for Core Data concurrency

secureManagedObjectContext = [[NSManagedObjectContext alloc] init];

init只是initWithConcurrencyType:的参数NSConfinementConcurrencyType的包装器。这使用线程限制模型创建上下文,该模型不能使用performBlock:performBlockAndWait:。只有使用较新(不过时!)队列限制模型的上下文才能使用这些方法,并且必须使用这些方法来访问属于它的上下文或对象。使用队列限制和专用队列创建上下文:

secureManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

如果您的代码已迁移到使用私有队列上下文,您也可以删除串行调度队列,因为私有队列上下文提供了相同的功能。