我在我的应用中设置了以下核心数据:
Persistent Store Coordinator
^ Background MOC (NSPrivateQueueConcurrencyType)
^ Main Queue MOC (NSMainQueueConcurrencyType)
这是初始化代码:
_backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_backgroundContext setPersistentStoreCoordinator:self.coordinator];
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainContext setParentContext:_backgroundContext];
我使用背景MOC导入大量数据。我还使用它在后台执行复杂的提取请求,然后将对象ID传递给主队列以使用这些ID获取对象。
这很有效。但是,我不知道如何让主队列MOC知道后台MOC中所做的更改。我知道如果我在主队列MOC上执行获取请求,它将获得更改,但这不是我想要的。
可以使用后台MOC发布的NSManagedObjectContextObjectsDidChangeNotification
通知并在主队列MOC上调用mergeChangesFromContextDidSaveNotification:
吗?这应该导致主队列MOC的NSManagedObjectContextObjectsDidChangeNotification
通知被触发。我正在我的视图控制器中侦听此通知,并检查userInfo
的更改并相应地重新显示数据。
我认为如果你有一个持久的商店协调员和两个附加的MOC,你通常会这样做。但是,当你有孩子/父母的情境时,我不确定这是否是正确的做法。
答案 0 :(得分:4)
让主MOC使用私有父MOC进行异步I / O很好。但是,您不应将该父MOC用于代表主MOC执行后台工作的任何内容。这有很多原因(其中包括与瞬态对象ID相关的性能和讨厌问题)。
如果您想对商店进行后台更新,我建议这样做。
PSC <--+-- PrivateMOC <---- MainMOC
|
+-- BackgroundPrivateMOC
这将允许后台操作导致主MOC中断最少,同时允许共享PSC缓存。
现在,共享数据......
MainMOC应该监听并合并BackgroundPrivateMO中的DidSave通知。
BackgroundMOC可以侦听和合并来自PrivateMOC的DidSave通知。
这允许合并仅使用永久对象ID并优化性能。
答案 1 :(得分:3)
我会说听NSManagedObjectContextObjectsDidChangeNotification
通知可能不是最佳解决方案。
我这样做的方式和工作方式如下。 这是主要的上下文创建:
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
_mainContext.persistentStoreCoordinator = _persistentStoreCoordinator;
以下是背景上下文创建:
_backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_backgroundContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
_backgroundContext.parentContext = self.mainContext;
现在,后台上下文仅用于写入(或读取)对象(可能在后台线程中)。主上下文仅用于从主队列中读取。 保存在背景上下文应该如下:
__block BOOL saved = [_backgroundContext save:error];
if (saved && _backgroundContext.parentContext) {
[_backgroundContext.parentContext performBlockAndWait:^{
saved = [self.parentContext save:error];
}];
}
此保存方法可确保将所有更改传播到主上下文。如果你在很多后台线程中做了很多工作,那就更熟悉performBlockAndWait:
方法,它可以在上下文中互斥。
如果您希望收到有关对象更改的通知,则无需收听通知,只需设置NSFetchedResultsController
并注册为其代理即可。