核心数据和NSOperation [英] Core Data and NSOperation

查看:160
本文介绍了核心数据和NSOperation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm currently working with an NSPersistentDocument subclass that uses NSOperation to import data in the background. As per the documentation, I'm observing the NSManagedObjectContextDidSaveNotification after saving in the background task and propagating the notification to the NSManagedObjectContext in the main thread using -mergeChangesFromContextDidSaveNotification:.

一切正常,但它为用户呈现一个奇怪的工作流程谁正在将数据导入到新文档中。他们需要在进行导入之前保存一个空文档(否则 -save:失败,因为文档尚未配置 NSPersistentStoreCoordinator 。)我没有看到一个方法,除了某种类型的新文档设置向导,确保 -writeToURL:ofType:forSaveOperation:originalContentsURL:error:

Everything works fine, but it presents a weird workflow for a user who's importing data into a new document. They need to save an empty document before doing the import (otherwise the -save: fails because the document hasn't configured a URL for the NSPersistentStoreCoordinator.) I don't see a way around this other than some kind of "new document setup" wizard that ensures -writeToURL:ofType:forSaveOperation:originalContentsURL:error: gets called before the import.

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

Also, it appears that an import task in the background precludes the use of an NSUndoManager on the main thread. (I'm assuming that it's unsafe to share the managed object context's undo manager across the threads.) From a user's point-of-view, there's no way to undo all the new objects created during the import.

我已经阅读了核心数据编程指南和Marcus Zarra的书,但我仍然是这个框架的新方面。希望我忽略了一些东西:如果不是,我会适应我的应用程序这些限制(Core Data的好处远远超过这些用户界面限制。)

I've read both the Core Data Programming Guide and Marcus Zarra's book, but I'm still new to this aspect of the framework. Hopefully, I've overlooked something: if not, I'll adapt my app to these restrictions (the benefits of Core Data far outweigh these user interface limitations.)

谢谢

-

根据Peter Hosey的建议,我添加了以下代码来创建导入之前的临时持久存储:

Based on Peter Hosey's suggestion below, I added the following code to create a temporary persistent store prior to the import:

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存储:

Then, after a file is selected in the save panel, the temporary persistent store is migrated to a SQLite store at the selected URL:

- (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];
}


推荐答案

专家,但从我从文档中可以知道,你会想从一个内存存储开始,直到用户(在自己的时间)保存文档。然后,发送协调器 a migratePersistentStore:toURL:options:withType:error:从内存存储到新的真正持久存储。请参阅该文档的一些基本细节(特别是关于您迁移的商店的命运)。

I'm nobody's Core Data expert, but from what I can tell from the docs, you'll want to start with an in-memory store until the user (in their own time) saves the document. Then, send the coordinator a migratePersistentStore:toURL:options:withType:error: message to change over from the in-memory store to the new truly-persistent store. See that document for some essential details (particularly regarding the fate of the store you migrate).

这篇关于核心数据和NSOperation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆