core-data - 核心数据和 NSOperation

标签 core-data nsoperation nsundomanager

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

一切正常,但它为将数据导入新文档的用户提供了一个奇怪的工作流程。他们需要在导入之前保存一个空文档(否则 -save: 会失败,因为文档没有为 NSPersistentStoreCoordinator 配置 URL。)除了某种“新文档设置”向导,确保 -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];
}

最佳答案

我不是核心数据专家,但从我从文档中可以看出,您需要从内存存储开始,直到用户(在他们自己的时间)保存文档。然后,发送协调器 a migratePersistentStore:toURL:options:withType:error: message从内存存储转换为新的真正持久化存储。有关一些基本细节(特别是关于您迁移的商店的命运),请参阅该文档。

关于core-data - 核心数据和 NSOperation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4925650/

相关文章:

ios - 修复我的网络事件指示器

objective-c - Core Data UndoManager 发送奇怪的 NS

ios - iPhone coredata删除通过关系连接的两个实体之间的记录

ios - 尝试将 Web 服务中的值保存到核心数据中

ios - NSOperation - 等待完成包括完成 block

ios - 一个一个保存 NSUndoManager 事务

ios - UIWebView中如何实现undo/redo

iphone - 体系结构错误的 undefined symbol

ios - 核心数据 : Fetching related objects in many-to-many relationship

ios - 从 NSOperation 子类读取数据到多个 View Controller