主要背景和推荐的合并政策;多线程CoreData应用程序中的私有上下文

时间:2014-02-26 09:35:21

标签: ios multithreading core-data merge

我已阅读并试图了解这样做的推荐实践,但我想就以下情况提出您的专家意见;

我使用CoreData并将主上下文分配给持久性存储协调器。

- (void) setupCoreDataStack
{
    self.managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]];
    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];

    NSURL *url = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"Model.sqlite"];

    NSDictionary *options = @{NSPersistentStoreFileProtectionKey: NSFileProtectionComplete,
                              NSMigratePersistentStoresAutomaticallyOption:@YES};
    NSError *error = nil;
    NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error];
    if (!store)
    {
        NSError *deleteError = nil;
        if ([[NSFileManager defaultManager] removeItemAtURL:url error:&deleteError])
        {
            error = nil;
            store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error];
        }

        if (!store)
        {
            // Also inform the user...
            NSLog(@"Failed to create persistent store. Error %@. Delete error %@",error,deleteError);
            abort();
        }
    }

    self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    self.mainManagedObjectContext.persistentStoreCoordinator = psc;
}

我所有异步工作线程(与后端同步,执行各种BLE / CoreBluetooth活动等)创建自己的私有上下文(来自异步调度线程),然后使用 performBlock 执行根据指南/建议最终保存私人背景和主要背景之前的工作;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                         (unsigned long)NULL), ^(void)
{
    //Create private context and lnk to main context..
    NSManagedObjectContext* privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

    //Link private context to main context...
    privateContext.parentContext = self.mainManagedObjectContext;

    //Perform login-mechanism in block
    [privateContext performBlock:^{

        //Do the work!
        ...
        ...

        //Merge changes to main context!
        NSError* error = nil;
        if (![privateContext save:&error])
            abort();

        //Save main context to persistent store coordinator
        [self.mainManagedObjectContext performBlockAndWait:^{

            NSError *mainError;
            if (![self.mainManagedObjectContext save:&mainError])
                abort();
        }];
    }];
});

我现在的问题是,合并政策在此设置中如何运作?当我为mainContext分配一个mergePolicy时,这是否适用于如何将更改从mainContext合并到PSC,或者当私有上下文合并到主上下文时?

我的理解是正确的,在此设置中使用 NSMergeByPropertyObjectTrumpMergePolicy ,如果分配给私有上下文,将确保私有上下文更改合并到主上下文,并且如果私有对象将被使用,则有冲突吗?或者我是否必须设置主要上下文的mergePolicy也可以工作?

感谢您的想法, /马库斯

1 个答案:

答案 0 :(得分:4)

通常,您希望在主NSManagedObjectContext上设置合并策略。但是我的第一个问题是,你是否遇到了合并冲突?如果您没有得到任何内容,那么您是否需要更改合并策略?

我倾向于保留默认策略(合并时出错),直到我遇到合并问题。否则,当您没有意识到存在合并情况时,您可能会通过合并工作掩盖问题。