1

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

_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 并处理数据的持久性。mainMOC 与 masterMOC 有父关系,用于为 UI 上的 FRC 提供数据,并帮助 FRC 代理监控刷新数据所做的更改。insertMOC 与 mainMOC 具有父关系,并使用 NSOperation 在单独的线程上创建,并已在 main 方法调用中实例化。cacheMOC 从插入类传递insertionMOC 以继承其属性。我已经按照上面的广告进行了所有这些工作,但是……在刷新数据时,我的应用程序崩溃了。

我看到这个问题的方式是,在插入MOC 删除它们之后,上下文之间存在一些混淆,即正确的 ManagedObjectID 集是什么。

这就是我删除旧 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];
}];

笔记。如果我没有获取 PermenentObjectIDsForObjects: 错误:此时应用程序将崩溃。

运行后,我不保存 inertionContext 因为这将触发带有 FRC 委托监视更改的 UI 刷新。相反,我收集新数据并将一个实体的一些结果插入到缓存中。为了使缓存工作,它需要创建一个获取请求以获取 managedObjectID 并找到重复项。正是在这一点上,应用程序崩溃了。

我对具有嵌套关系的 MOC 文档的理解是,fetchRequest 将通过所有 MOC 从保存在persistantStore 中的所有 MOC 中提取数据。但如果是这种情况,我不应该在获取它们以删除它们时强制 insertMOC 获取 PermanentOBJectID。话虽如此,看来我的缓存能够从persistanStore 获取permanentID,因此它崩溃了。

cacheMOC 是否应该像其他设置一样与插入MOC 建立关系?缓存是否也应该设置在它自己的私有线程线程上以使其工作?我是否应该锁定 mainMOC 以防止 FRC 更新结果,然后保存 insertMOC 以保留删除?

4

1 回答 1

2

您不需要获得永久 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];

您的 insertContext 应该将 masterMOC 作为父级。

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

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

于 2013-04-03T19:35:40.310 回答