【问题标题】:Strange behavior when using child/parent NSManagedObjectContext使用子/父 NSManagedObjectContext 时的奇怪行为
【发布时间】:2012-06-28 15:46:23
【问题描述】:

我正在开发一个应用程序,我需要在后台线程上计算事物(多秒操作)和写入事物(与服务器同步数据)。

因此,我使用了两个 NSManagedObjectContexts (MOC),一个子对象和一个父对象,它们必须始终保持同步。为确保它们同步,我总是将数据编辑/添加到子 MOC,以便使用以下模式将其推送到主 MOC:

[childMOC performBlock:^{

    MyObject *myObject = *create new object in childMOC*

    [childMOC save:&error];

    [mainMOC performBlock:^{
        [mainMOC save:&error];
        // Is this mandatory to make it work correctly?
        // [childMOC performBlock:^{
        //     [childMOC refreshObject:myObject mergeChanges:NO];
        // }];
    }];
}];

过了一会儿,我在后台上下文中似乎有同一个对象的两个版本,一个具有临时 ID,另一个具有永久 ID。如果我例如将子对象添加到“真实”对象(通过将新的永久 ID 从主 MOC 传递给子 MOC)我在后台 MOC 中检索对象时没有看到这些对象,因为它是缓存的旧临时对象。

我已经看到上面的模式被大量使用了,但是没有人提到这个临时/永久 ID 问题似乎很奇怪。

  1. 在一个上下文中它可以是同一个对象的两个版本感觉不对。如果我将 NSManagedObjectID 传递给子 MOC 并检索它,子 MOC 是否应该更新我现有的对象而不是创建一个新对象并将我的旧临时对象保留为缓存默认值?

  2. 是否需要在我创建对象的每个位置使用注释行?

  3. 或者它可能与 mergeChangesFromContextDidSaveNotification 一起使用,会产生相同的效果吗?

【问题讨论】:

    标签: objective-c core-data ios5 nsmanagedobjectcontext


    【解决方案1】:

    我遇到了这个问题,解决方案是确保父 MOC 上的所有操作都使用 performBlock: 完成,即使是初始设置:

        parentManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        [parentManagedObjectContext performBlock:^{
            [parentManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
            [parentManagedObjectContext setPersistentStoreCoordinator:coordinator];
        }];
    

    一旦我这样做了,我的孩子 MOC 就开始接受变化。

    【讨论】:

    • 这对我不起作用,即使在制作所有 mocs NSMainQueue 时也是如此。我使用了 performBlockAndWait 而不是 performBlock。但我不认为这是一个原因
    【解决方案2】:

    我的解决方案是:

    1) 使用背景 MOC 作为父 MOC,主 MOC 作为子 MOC。作为奖励,我不需要保存主 MOC 即可获得永久 ID。

    [DC.backgroundMOC performBlock:^{
        // Add, save and update managed objects
        [DC saveContext]; // The changes is being pushed to the main context
    }];
    

    2) 使用 NSManagedObjectContextDidSaveNotification 使主 MOC 保持最新(主 MOC 正在更新 UI)

    - (void) backgroundMOCSaved:(NSNotification*)notification {
        [mainMOC performBlock:^{
            [mainMOC mergeChangesFromContextDidSaveNotification:notification];
        }];
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-13
      • 2021-05-03
      • 1970-01-01
      • 1970-01-01
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多