我正在使用“老派”核心数据并发模型。换句话说,我有一个主要NSManagedObjectContext
,它是用NSMainQueueConcurrencyType
创建的,任何网络请求都会在新创建的NSPrivateQueueConcurrencyType
上下文中处理JSON响应数据。上下文共享persistentStoreCoordinator
而不是使用parentContext
,并且手动完成上下文合并。在iOS 8中合并核心数据NSManagedObjectContexts
由于iOS 8,一些我的设备展示了似乎上下文合并无法正常工作的行为。在观察NSManagedObjectContextDidSaveNotification
后,我通过在我的主要上下文中调用mergeChangesFromContextDidSaveNotification
将合并更改合并到我的主要上下文中。之后,我尝试使用objectWithID:
获取活动对象图的主要上下文版本,该表格似乎可以正常工作。但是,仔细观察返回的对象后,任何NSSet
关系都是空的,即使第二上下文版本具有它们。*
奇怪的是,相同的代码在运行iOS 8的iPhone 6/6 +上产生准确的上下文合并。我的iOS 7 iPod Touch 5G可以正常工作。始终失败的设备是相同的iOS 8 iPod Touch 5G。它也适用于所有模拟器。
是否有其他人看到过类似的行为或对于可能导致此设备特定的核心数据问题的看法?提前致谢。
__block id toReturn = [self processResponse:responseData]; //Complete object graph from api.
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setPersistentStoreCoordinator:[self persistentStoreCoordinator]]; //shared PSC
[context setUndoManager:nil];
[context setStalenessInterval:0];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
NSManagedObjectContext *mainContext = [self mainContext];
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
object:context
queue:[NSOperationQueue mainQueue]
usingBlock:
^(NSNotification *notification) {
[mainContext mergeChangesFromContextDidSaveNotification:notification];
NSManagedObjectID *managedId = [toReturn objectID];
NSManagedObject *mainContextVersion = [mainContext objectWithID:managedId];
toReturn = mainContextVersion; //*This is where the object graph is incomplete
}];
//Save context, will fire NSManagedObjectContextDidSaveNotification.
NSError *errorWhileSaving;
[context save:&errorWhileSaving];
你的第一段概括您的问题很好。它不是特定于设备的,它与使用队列限制和合并通知有关 - 它们不能很好地协同工作,并且如果使用performBlockAndWait,由于缺少用户事件处理,您将很难诊断问题。 – quellish 2014-11-05 19:36:05
我没有使用'performBlockAndWait.'你的意思是“没有使用”@quellish?如果是这样的话,我只是觉得我只需要使用'performBlock'或'performBlockAndWait',因为'save'是一个同步事件,并且通知仅在保存完成后触发。在任何情况下,我都尝试在'performBlockAndWait'块中包装'save'和'mergeChanges ...'调用,结果没有变化。 – Keller 2014-11-05 20:45:44
我的意思是“是”。如果您正在使用除NSConfinementConcurrencyType之外的任何内容创建的上下文,则除了上下文自己的存取方法外,您必须使用块方法来访问上下文的任何部分,包括对象及其属性。 – quellish 2014-11-05 21:31:45