3

我有一个使用 CoreData 的基于文档的 Cocoa 应用程序,它可以导入大量数据。由于此导入需要一些时间,因此我在后台执行此操作,但由于NSManagedObjectContext不是线程保存,因此我使用文档persistentStoreCoordinator的of在后台线程中managedObjectContext创建了一个新线程。NSManagedObjectContext现在,当导入完成时,我保存背景managedObjectContext以通知文档的主线程managedObjectContext更改并合并它们。据我了解,这就是应该使用 CoreData 进行并发的方式。

但有时,当我调用时persistentStoreCoordinator没有会导致保存失败和应用程序崩溃。我正在使用自动保存和所有(在 OS X 10.8 上基本上是未修改的 NSPersistentDocument),所以我认为我不必关心它是如何保存的,它会“正常工作”。persistentStore[managedObjectContex save:]

显然,事实并非如此。我尝试强制执行自动保存操作,希望通过在我的文档子类[self autosaveDocumentWithDelegate:self didAutosaveSelector:@selector(document:didAutosave:contextInfo:) contextInfo:nil];的末尾调用来创建一个 persistentStore windowControllerDidLoadNib:,但这似乎并没有改变任何东西。委托回调 ( - (void)document:(NSDocument *)document didAutosave:(BOOL)didAutosaveSuccessfully contextInfo:(void *)contextInfo) 实际上表明自动保存是成功的,尽管任何 fileURL 或相关访问器都没有返回非 nil 的东西,也没有创建持久存储。

我也想过给-(BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError *__autoreleasing *)error自己打电话,但我不知道用什么 URL 让它像普通的自动保存一样。我检查了backupFileURL,但最后都还是fileURLnil 。事实上,他们甚至没有被调用,所以我不知道如何获得“正确”的 URL。autosavedContentsFileURLwindowControllerDidLoadNib:writeToURL:...configurePersistentStoreCoordinatorForURL:...

为了更好地理解创建持久存储方式和时间,我在writeToURL:...和中设置了断点configurePersistentStoreCoordinatorForURL:...。我注意到configurePersistentStoreCoordinatorForURL:当应用程序失去最前面的状态时会调用它。但是,当我刚刚创建一个新文档并尝试在创建后立即导入某些内容时(无需先切换到另一个应用程序以导致创建 persistentStore),它就会崩溃。如果我切换到另一个应用程序,则会创建商店并且一切正常。顺便说一句,用于以这种方式创建的 persistentStore 的 URL 始终位于 temp 目录中的某个位置。

难道我做错了什么?我不必调用 [managedObjectContext save:] 来通知其他 managedObjectContext 更改吗?如何强制文档创建其临时持久存储?为什么不调用autosaveDocumentWithDelegate:...实际保存文档(并因此创建一个persistentStore)?

有关的:

4

1 回答 1

3

我解决了一个类似的问题:我需要生成永久对象 ID,这需要存在持久存储。就像您指出的那样,尚未自动保存的无标题文档没有持久存储。

这个简短的片段来自我的 NSWindowController 子类:

- (void) awakeFromNib {
    //hacky way to get an autosave to generate an NSPersistentStore.
    GSNativeDocument *doc = self.document;
    [doc updateChangeCount:NSChangeDone];
    [doc autosaveDocumentWithDelegate:self didAutosaveSelector:@selector(document:didAutosave:contextInfo:) contextInfo:nil];
}

//called by the autosave operation started in awakeFromNib.
- (void)document:(NSDocument *)document didAutosave:(BOOL)didAutosaveSuccessfully contextInfo:(void *)contextInfo
{
    GSNativeDocument *doc = self.document;
    [doc updateChangeCount:NSChangeUndone];
}

为什么更新更改计数会创建“真正的”自动保存,而其他所有诱导自动保存的方法都没有?我没有任何线索。我在 1 月初向 Apple 提交了这个错误并在开发论坛上发布,但他们没有回复。

于 2013-02-01T18:57:44.867 回答