我目前正在使用一个用于在后台导入数据的NSPersistentDocument
子类。NSOperation
根据文档,我正在观察NSManagedObjectContextDidSaveNotification
在后台任务中保存后并NSManagedObjectContext
使用-mergeChangesFromContextDidSaveNotification:
.
一切正常,但它为将数据导入新文档的用户呈现了一个奇怪的工作流程。他们需要在导入之前保存一个空文档(否则会-save:
失败,因为该文档没有为NSPersistentStoreCoordinator
.-writeToURL:ofType:forSaveOperation:originalContentsURL:error:
在导入之前被调用。
此外,后台的导入任务似乎排除了NSUndoManager
在主线程上使用。(我假设跨线程共享托管对象上下文的撤消管理器是不安全的。)从用户的角度来看,没有办法撤消在导入期间创建的所有新对象。
我已经阅读了Core Data Programming Guide和 Marcus Zarra 的书,但我对框架的这方面仍然很陌生。希望我忽略了一些事情:如果没有,我会让我的应用程序适应这些限制(Core Data 的好处远远超过这些用户界面限制。)
谢谢你的时间!
--
根据下面 Peter Hosey 的建议,我添加了以下代码以在导入之前创建一个临时持久存储:
NSPersistentStoreCoordinator *persistentStoreCoordinator = [self.managedObjectContext persistentStoreCoordinator];
if ([[persistentStoreCoordinator persistentStores] count] == 0) {
// create an in-memory store to use temporarily
NSError *error;
NSPersistentStore *persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&error];
if (! persistentStore) {
NSLog(@"error = %@", error); // TODO: better error handling
}
}
然后,在保存面板中选择文件后,临时持久存储将迁移到所选 URL 处的 SQLite 存储:
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error
{
NSPersistentStoreCoordinator *persistentStoreCoordinator = [self.managedObjectContext persistentStoreCoordinator];
for (NSPersistentStore *persistentStore in [persistentStoreCoordinator persistentStores]) {
if (persistentStore.type == NSInMemoryStoreType) {
// migrate the in-memory store to a SQLite store
NSError *error;
NSPersistentStore *newPersistentStore = [persistentStoreCoordinator migratePersistentStore:persistentStore toURL:absoluteURL options:nil withType:NSSQLiteStoreType error:&error];
if (! newPersistentStore) {
NSLog(@"error = %@", error); // TODO: better error handling
}
}
}
return [super writeToURL:absoluteURL ofType:typeName forSaveOperation:saveOperation originalContentsURL:absoluteOriginalContentsURL error:error];
}