我目前正在使用NSPersistentDocument
子类,该子类使用NSOperation
在后台导入数据。根据文档,我在保存后台任务后观察NSManagedObjectContextDidSaveNotification
并使用NSManagedObjectContext
将通知传播到主线程中的-mergeChangesFromContextDidSaveNotification:
。
一切正常,但它为将数据导入新文档的用户提供了一个奇怪的工作流程。他们需要在导入之前保存一个空文档(否则-save:
会失败,因为文档没有为NSPersistentStoreCoordinator
配置URL。)除了一些之外,我看不到其他方法一种“新文档设置”向导,可确保在导入之前调用-writeToURL:ofType:forSaveOperation:originalContentsURL:error:
。
此外,后台的导入任务似乎排除了在主线程上使用NSUndoManager
。 (我假设跨线程共享托管对象上下文的撤消管理器是不安全的。)从用户的角度来看,没有办法撤消导入过程中创建的所有新对象。
我已经阅读了核心数据编程指南和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];
}
答案 0 :(得分:5)
我是没有人的核心数据专家,但从我从文档中可以看出,你需要从内存存储开始,直到用户(在他们自己的时间内)保存文档。然后,发送协调器a migratePersistentStore:toURL:options:withType:error:
message以从内存存储库转换到新的真正持久存储区。请参阅该文档以获取一些基本信息(特别是有关您迁移的商店的命运)。
答案 1 :(得分:2)
我对工作流/保存部分的第一个想法是,如果尚未为文档创建持久性存储,则创建临时的内存存储,以便导入的数据将保存到该存储(尽管文档/窗口仍将标记为脏)。然后,一旦用户将文档保存为真实,您将重新配置协调器以删除内存存储并将其替换为磁盘存储,因此所有进一步的保存将转到磁盘。
答案 2 :(得分:2)
我不是100%熟悉Mac的东西,但我确信你可以在用户保存之前使用内存中的持久存储,然后在该操作之后添加sql / plist存储。
可能更好的方法是在标准临时目录中创建磁盘持久性存储,并在用户单击以保存时将其移动。
答案 3 :(得分:0)
您在设置协调器时是否尝试过设置临时文件URL? 您应该能够在主线程上撤消-mergeChangesFromContextDidSaveNotification :.无需在后台线程上为MOC注册撤消管理器。