如何忽略NSManagedObjectContextWillSaveNotification中mergeChangesFromContextDidSaveNotification的更改

Z S*_*Z S 8 core-data nsmanagedobject nsmanagedobjectcontext ios

我正在使用私有托管对象上下文来创建一些新对象到持久性存储中,然后在保存私有MOC之后,使用它们将它们合并到主MOC中mergeChangesFromContextDidSaveNotification.这工作正常,并根据需要更新UI,并且NSManagedObjectContextWillSaveNotification不会在此处调用mainMOC.

然后我对mainMOC使用UI 进行了一些更改,并听取了NSManagedObjectContextWillSaveNotification.通知已发布,但它不仅包含我所做的编辑,还包含从PrivateMOC使用中合并的对象mergeChangesFromContextDidSaveNotification.

有没有办法mainContext在后续contextDidChange通知中忽略从另一个上下文合并到的更改?

这是设置:

- (void) loadData {
   privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];

   privateContext.persistentStoreCoordinator = self.mainContext.persistentStoreCoordinator;

   [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(contextWillSave:)
                                             name:NSManagedObjectContextWillSaveNotification
                                           object: self.mainContext];

   NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:record.recordType inManagedObjectContext: self.privateContext];

   // fill in object

   if ([self.privateContext hasChanges]) {
       [self savePrivateContextAndMergeWithMainContext: self.privateContext];
   }
}

- (void) savePrivateContextAndMergeWithMainContext: (NSManagedObjectContext *) privateContext {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(privateContextDidChange:) name:NSManagedObjectContextDidSaveNotification object:privateContext];
    __block NSError *error = nil;
    [privateContext performBlockAndWait:^{
        NSLog(@"PrivateContext saved");
        [privateContext save:&error];
    }];


    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:privateContext];

    if (error) {
        NSLog(@"error = %@", error);
    }
}

- (void) privateContextDidChange: (NSNotification *) notification{

    [self.mainContext performBlockAndWait:^{
        NSLog(@"merged into mainContext");
        [self.mainContext mergeChangesFromContextDidSaveNotification:notification];
    }];
}
Run Code Online (Sandbox Code Playgroud)

这工作正常并保存私有上下文并合并到mainContext不会触发contextWillSave通知.但是,在从UI(在主MOC上)编辑数据时,会触发通知并包含先前使用私有MOC保存的数据.

希望很清楚.如果我应该包含其他任何内容,请告诉我.

- 更新 -

似乎问题是专门从私有上下文中删除对象.从私有上下文中删除并调用mergeChangesFromContextDidSaveNotification主MOC后,mainMoc的deletedObjects集仍然显示已删除的对象.私有上下文中的插入或更新不会发生这种情况.这记录在哪里?可能的解决方法是什么?

que*_*ish 1

Core Data 已经存在很多年了,随着时间的推移,并发模型也不断发展。

“线程限制”和“锁定”并发模型使用通知来传达上下文之间的更改。保存上下文时,将广播一条通知,其中包含有关更改的信息。该信息可用于将一个上下文中的更改合并到其他上下文中。这从来没有很好地扩展,并且通常是应用程序的主要痛点。“锁定”和“线程限制”模型已经过时很多年了。

当引入“队列限制”时,“嵌套上下文”的概念也随之引入。上下文可以有父上下文,当保存子上下文时,这些更改会自动传递给父上下文(不再进一步)。当您使用队列限制时,这是在上下文之间传达更改的推荐方法。

不建议您mergeChangesFromContextDidSaveNotification:NSPrivateQueueConcurrencyType上下文一起使用。

Core Data 代表您执行大量内部簿记和变更跟踪。通常,在保存操作期间,信息会被聚合和合并 - 这是操作的一部分processPendingChanges。当在 a 内部执行保存操作时,performBlockAndWait:这可能不会发生,或者可能不完整 - 这会导致更改(以及任何更改通知)不完整或根本不发生。performBlockAndWait:是可重入的,与进程不兼容processPendingChanges。相反,使用它performBlock:会导致更一致的行为。

如果您使用嵌套上下文来传达更改而不是通知,那么您在问题中描述的问题将得到解决。