4

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

因此,我使用两个 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 一起使用,会产生相同的效果吗?

4

2 回答 2

3

我的解决方案是:

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];
    }];
}
于 2012-07-29T20:27:52.800 回答
1

I had this problem and the solution was making sure all operations on the parent MOC are done with performBlock:, even the initial setup:

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

Once I did this, my child MOCs started picking up changes.

于 2012-07-02T22:05:58.710 回答