我目前正在使用NSPersistentDocument
子類,它使用NSOperation
在後臺導入數據。根據文檔,我在保存後臺任務後觀察NSManagedObjectContextDidSaveNotification
,並在主線程中使用-mergeChangesFromContextDidSaveNotification:
將通知傳播到NSManagedObjectContext
。核心數據和NSOperation
一切工作正常,但它爲將數據導入新文檔的用戶呈現了一個奇怪的工作流程。他們需要在導入之前保存一個空文檔(否則-save:
失敗,因爲該文檔沒有配置NSPersistentStoreCoordinator
的URL)。除了某種「新文檔設置」嚮導之外,我沒有看到任何解決方法確保-writeToURL:ofType:forSaveOperation:originalContentsURL:error:
在導入之前被調用。
此外,似乎在後臺導入任務排除在主線程上使用NSUndoManager
。 (我假設跨線程共享託管對象上下文的撤銷管理器是不安全的。)從用戶的角度來看,無法撤消在導入過程中創建的所有新對象。
我已經閱讀了核心數據編程指南和Marcus Zarra的書,但我仍然對這個框架的這方面不熟悉。希望我忽略了一些事情:如果沒有,我會使我的應用適應這些限制(Core Data的好處遠遠超過這些用戶界面限制。)
感謝您的時間!
-
基於以下彼得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
}
}
然後,在保存時選擇文件後面板,臨時持久存儲被遷移到一個SQLite儲存在選定的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];
}
就像你在Mac上一樣,你不能在內存存儲中使用內存,然後在準備好時切換上下文以使用基於文件的存儲?上面的方法也可以解決撤銷問題,因爲如果需要的話,你可以放棄整個上下文堆棧。似乎我在寫這篇文章的時候大家寫的都一樣:) – Jonathan 2011-02-07 19:48:59