Core Data を使用し、iCloud と同期するアプリを作成しています。これを行うには、以下に示すように設定した UIManagedDocument があります。
UIManagedDocument *document = [[UIManagedDocument alloc] initWithFileURL:[self iCloudStoreURL]];
document.persistentStoreOptions = @{NSPersistentStoreUbiquitousContentNameKey: [document.fileURL lastPathComponent], NSPersistentStoreUbiquitousContentURLKey: [self iCloudCoreDataLogFilesURL], NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption : @YES};
self.mydoc = document;
[document release];
[document.managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentContentsChanged:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:document.managedObjectContext.persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentStateChanged:) name:UIDocumentStateChangedNotification object:document];
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.mydoc.fileURL path]]) {
// does not exist on disk, so create it
[self.mydoc saveToURL:self.mydoc.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self populateTable];//synchronous call. few items are added
[self iCloudIsReady];
}];
} else if (self.mydoc.documentState == UIDocumentStateClosed) {
// exists on disk, but we need to open it
[self.mydoc openWithCompletionHandler:^(BOOL success) {
[self iCloudIsReady];
}];
} else if (self.mydoc.documentState == UIDocumentStateNormal) {
// already open and ready to use
}
}
このアプローチに関する私の問題は、2 つのデバイスでアプリを実行しているときに「楽観的ロックの失敗」が発生し続けることです。Apple の Core Data ドキュメントで、この種の問題を「回避」する方法は、マージ ポリシーを NSMergeByPropertyObjectTrumpMergePolicy に設定することであると読みました。
私が見つけられないことの1つは、これを修正する方法です。たとえば、これが発生する可能性がある場合、アプリは少なくともこの動作を認識し、処理する準備ができている必要があります。しかし、私はこれを処理する方法がわかりません。たとえば、競合するオブジェクトを取得して解決するにはどうすればよいですか? このエラーが発生するたびに、ドキュメントを保存しようとすると UIDocumentStateSavingError が発生し始めます。このエラーの発生を止める唯一の方法は、アプリを強制終了して再起動することです。