我有一个基于文档的核心数据应用程序(在 Mac OS X 10.5 及更高版本上运行),我试图NSManagedObjectContext
在主线程上使用两个 's。我想将次要上下文中所做的更改合并到我的主要(主要)上下文中。此外,我希望从辅助上下文中合并的更改是可撤消的,并导致文档被标记为“脏”。我想我的问题类似于“撤消在主线程之外执行的核心数据插入”但是,ATM,我没有使用不同的线程。
我一直在观察NSManagedObjectContextDidSaveNotification
(调用时从第二个上下文发送-[self.secondaryContext save:]
)是这样的:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mocDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.secondaryContext];
在-mocDidSave:
观察者调用的方法中,我尝试在主要上下文上使用-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:]
将次要上下文中的更改合并到主要上下文中:
- (void)mocDidSave:(NSNotification *)notification
{
[self.primaryContext mergeChangesFromContextDidSaveNotification:notification];
}
但是,虽然插入的对象很容易出现在我的数组控制器中,但文档没有标记为脏,并且isInserted
新添加的托管对象的属性没有设置为 YES。插入(到主要上下文中)也是不可撤消的。
对任何插入的对象进行重新故障至少会将文档标记为脏,但插入仍然不可撤消:
- (void)mocDidSave:(NSNotification *)notification
{
[self.primaryContext mergeChangesFromContextDidSaveNotification:notification];
for (NSManagedObject *insertedObject in [[notification userInfo] objectForKey:NSInsertedObjectsKey]) {
[self.primaryContext refreshObject:[self.primaryContext existingObjectWithID:[insertedObject objectID] error:NULL] mergeChanges:NO];
}
}
Wrt -mocDidSave:
,我通过自定义实现获得了更好的结果:
- (void)mocDidSave:(NSNotification *)notification
{
NSDictionary *userInfo = [notification userInfo];
NSSet *insertedObjects = [userInfo objectForKey:NSInsertedObjectsKey];
if ([insertedObjects count]) {
NSMutableArray *newObjects = [NSMutableArray array];
NSManagedObject *newObject = nil;
for (NSManagedObject *insertedObject in insertedObjects) {
newObject = [self.primaryContext existingObjectWithID:[insertedObject objectID] error:NULL];
if (newObject) {
[self.primaryContext insertObject:newObject];
[newObjects addObject:newObject];
}
}
[self.primaryContext processPendingChanges];
for (NSManagedObject *newObject in newObjects) {
[self.primaryContext refreshObject:newObject mergeChanges:NO];
}
}
NSSet *updatedObjects = [userInfo objectForKey:NSUpdatedObjectsKey];
if ([updatedObjects count]) {
NSManagedObject *staleObject = nil;
for (NSManagedObject *updatedObject in updatedObjects) {
staleObject = [self.primaryContext objectRegisteredForID:[updatedObject objectID]];
if (staleObject) {
[self.primaryContext refreshObject:staleObject mergeChanges:NO];
}
}
}
NSSet *deletedObjects = [userInfo objectForKey:NSDeletedObjectsKey];
if ([deletedObjects count]) {
NSManagedObject *staleObject = nil;
for (NSManagedObject *deletedObject in deletedObjects) {
staleObject = [self.primaryContext objectRegisteredForID:[deletedObject objectID]];
if (staleObject) {
[self.primaryContext deleteObject:staleObject];
}
}
[self.primaryContext processPendingChanges];
}
}
这会导致我的数组控制器得到更新,文档被标记为脏,并且插入和删除是不可撤销的。但是,我仍然遇到无法撤消的更新问题。我是否应该手动循环遍历所有 updatedObjects 并用于-[NSManagedObject changedValues]
重新应用主上下文中的更改?
当然,这种自定义实现会在主上下文中从辅助上下文中复制大量工作。是否有任何其他/更好的方法可以在两个上下文之间进行合并,同时将合并保持为可撤消的步骤?