Core Data: How to merge inserts/updates/deletes between two NSManagedObjectContext's while maintaining the merge as an undoable step?
我有一个基于文档的Core Data应用程序(在Mac OS X 10.5及更高版本上运行),试图在主线程上使用两个
我一直在观察
1 2 3 4 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mocDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.secondaryContext]; |
在观察者调用的
1 2 3 4 | - (void)mocDidSave:(NSNotification *)notification { [self.primaryContext mergeChangesFromContextDidSaveNotification:notification]; } |
但是,虽然说插入的对象很容易出现在我的阵列控制器中,但是文档没有被标记为脏,并且新添加的管理对象的
对所有插入的对象进行重新故障处理将至少将文档标记为脏,但是插入仍不可撤消:
1 2 3 4 5 6 7 8 | - (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]; } } |
W.r.t。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | - (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]; } } |
这将导致我的数组控制器被更新,文档被标记为脏文件以及插入
如果您不使用单独的线程,则实际上不需要分开上下文。在同一线程上使用两个上下文会增加复杂性,但不会增加任何好处。如果您不确定是否要使用线程,那么我强烈建议您仅使用一个上下文。过早的优化是万恶之源。
保存重置撤消管理器,因此您无法使用
执行任何可以撤消的操作。如您所见,您可以欺骗应用程序以使其认为文档脏了,但是您不能强迫撤消管理器记住过去的保存。
做到这一点的唯一方法是无限撤消,就是在后台保存文档的多个版本。 IIRC,您还可以序列化撤消管理器,以便可以将其写入文件并重新加载到回溯。