核心数据和NSOperation

cho*_*rry 5 core-data nsoperation nsundomanager

我目前正在使用一个NSPersistentDocument子类,用于NSOperation在后台导入数据.根据文档,我正在观察NSManagedObjectContextDidSaveNotification后台任务中的保存并将通知传播到NSManagedObjectContext主线程中-mergeChangesFromContextDidSaveNotification:.

一切正常,但它为将数据导入新文档的用户提供了一个奇怪的工作流程.他们需要在导入之前保存一个空文档(否则-save:失败,因为文档没有为其配置URL NSPersistentStoreCoordinator.)除了某种"新文档设置"向导确保我没有办法解决这个问题.-writeToURL:ofType:forSaveOperation:originalContentsURL:error:在导入之前调用.

此外,后台的导入任务似乎排除了NSUndoManager在主线程上使用a.(我假设跨线程共享托管对象上下文的撤消管理器是不安全的.)从用户的角度来看,没有办法撤消导入期间创建的所有新对象.

我已经阅读了核心数据编程指南和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
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在保存面板中选择文件后,临时持久性存储将迁移到所选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];
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*sey 5

我是没有人的核心数据专家,但从我从文档中可以看出,你需要从内存存储开始,直到用户(在他们自己的时间)保存文档.然后,向协调器发送一条migratePersistentStore:toURL:options:withType:error:消息,以便从内存存储区切换到新的真正持久存储区.请参阅该文档以获取一些基本详细信息(特别是有关您迁移的商店的命运).