Core data 使用具有关系的多个NSManagedObjectContext时的混淆

Core data 使用具有关系的多个NSManagedObjectContext时的混淆,core-data,nsmanagedobjectcontext,Core Data,Nsmanagedobjectcontext,我使用四个NSManagedObjectContext来管理从存储在服务器上的源检索的数据的插入和删除。主运行中心之间的关系设置如下 _masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [_masterManagedObjectContext setPersistentStoreCoordinator:_psc]

我使用四个NSManagedObjectContext来管理从存储在服务器上的源检索的数据的插入和删除。主运行中心之间的关系设置如下

_masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
 [_masterManagedObjectContext setPersistentStoreCoordinator:_psc];

_mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:initWithConcurrencyType:NSMainQueueConcurrencyType];
 [_mainManagedObjectContext setParentContext:self.masterManagedObjectContext];

 _insertionContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_insertionContext setParentContext:self.mainManagedObjectContext];

_cacheContext = _insertionContext;
如您所见,masterMOC链接到persistantStoreCordinator并处理数据的持久性。主MOC与主MOC有父关系,用于向UI上的FRC提供数据,并帮助FRC代表监控刷新数据所做的更改。insertionMOC与mainMOC具有父关系,并且使用NSOperation在单独的线程上创建,并且已在main方法调用中实例化。cacheMOC从插入类传递insertionMOC以继承其属性。我的所有这些都可以像上面宣传的那样工作,但是……当涉及到刷新数据时,我的应用程序崩溃了

在我看来,问题在于,在insertionMOC删除ManagedObjects后,上下文之间存在一些混淆,即ManagedObjects的正确集合是什么

这就是我删除旧ManagedObjects的方式

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Event" inManagedObjectContext:_insertionContext]];
[fetchRequest setIncludesPropertyValues:NO];
NSError *error;
NSArray *array = [NSArray array];
array = [_insertionContext executeFetchRequest:fetchRequest error:&error];
[self.insertionContext obtainPermanentIDsForObjects:array error:&error];

if (array.count >0 && [self.kEntity isEqualToString:@"Event"]) {
     [array enumerateObjectsUsingBlock:^(Event *obj, NSUInteger idx, BOOL *stop) {
     [_insertionContext deleteObject:obj];
}];
注意。如果我没有获得PermenentObjectsForObjects:error:应用程序将在此时崩溃

运行此操作后,我不会保存inertionContext,因为这将触发UI刷新,FRC委托将监视更改。相反,我收集新数据并将一个实体的一些结果插入缓存。为了使缓存工作,它需要创建一个获取请求来获取ManagedObjects并查找重复项。就在这时,应用程序崩溃了

我对具有嵌套关系的MOC文档的理解是,fetchRequest将从保存在persistantStore中的MOC中提取所有MOC的数据。但如果是这种情况,我就不需要在获取永久对象以删除它们时强制insertionMOC获取它们。说到这里,我的缓存似乎能够从persistanStore获取permanentid,结果它崩溃了


cacheMOC是否应该设置为与insertionMOC的关系?缓存是否也应该设置为发生在它自己的私有线程上以使其工作?我是否应该锁定mainMOC以防止FRC更新结果,然后保存insertionMOC以保留删除?

您不需要获取永久ID。如果您在复制/粘贴过程中更改代码,则您有一个循环引用,它可能只是一个输入错误:

_masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
 [_masterManagedObjectContext setPersistentStoreCoordinator:_psc];

_mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:initWithConcurrencyType:NSMainQueueConcurrencyType];
//Possible typo due to editing code down to paste as a question
 [_mainManagedObjectContext setParentContext:_masterManagedObjectContext];
我认为你对cacheMOC的意图没有实现。如果在服务器更新启动时它应该是当前显示数据(mainMOC)的相同副本,那么它应该是一个单独分配的对象,具有mainMOC的parentContext

_cacheContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_cacheContext setParentContext:self.mainContext];
您的insertionContext应该以masterMOC作为父级

 _insertionContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_insertionContext setParentContext:_masterManagedObjectContext];

现在,当您使用insertionContext更新完数据后,只需保存它,并(可选)刷新mainMOC以使用更改更新UI

这不是打字错误。我特意以这种方式设置关系,使所有MOC自动更新,并触发FRC委托更新与主MOC关联的UITableView。我已经确认了这一点,当我在禁用cacheMOC的情况下刷新数据时,它看起来非常快。以masterMOC为父对象设置insertionContext意味着只有当mainMOC侦听了保存通知时,FRC委托才会收到更改通知。[\u mainManagedObjectContext合并更改fromContextDidSaveNotification:saveNotification];这要慢得多。再看看我把评论放在哪里。您正在将
\u masterManagedObjectContext
parentContext设置为(大概)自身。Doh!我在看你的代码,不是我的。对不起,我的错。我会马上修复它。如果这是你的代码中的实际内容,那可能会导致你永久性身份证的问题。除非实现一个NSPersistentStore,否则您永远不必使用它们。这就解释了为什么如果我没有获取insertionMOC永久ID的代码行来删除对象,它会在较早的时候崩溃。嗯,我想没有别的选择了,只能像你建议的那样建立关系。cacheMOC的fetchRequest中永远不会有正确的对象。