OK、これは私を夢中にさせています。
UImanageddocument を使用する 2 つのスレッドがあり、1 つはユーザーが選択を行うメイン コンテキストにあり、独自の moc を持つバックグラウンド スレッドは、タイムスタンプに従ってデータをサーバーと同期します。
1. メイン コンテキストにオブジェクトを追加する 2. バックグラウンドで同期する 3. バックグラウンドから保存する 4. メイン コンテキスト - メイン スレッドから同じオブジェクトを再度変更してみてください
NSMergeConflict が発生します
コンテキストを初期化する方法を示すために、多くの無関係なコードを除いて私のコードをいくつか含めます。誰かが私を啓発できることを願っています。これらの分野ではコアデータが扱いにくいことはわかっています。
メインスレッドで (アプリケーションでオプションを使用してロードを終了しました):
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; //get the default user documents folder
url = [url URLByAppendingPathComponent:DATABASENAME];
UIManagedDocument *doc = [[UIManagedDocument alloc] initWithFileURL:url];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
doc.persistentStoreOptions = options;
[doc.managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
self.database=doc;
self.mainManagedObjectContext=self.database.managedObjectContext;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDataModelChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.database.managedObjectContext];
以降:
- (void)handleDataModelChange:(NSNotification *)note
{
[self save];
}
-(void) save
{
[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
batch_save=!success;
NSLog(@"save success %d",success);
}];
}
そして、バックグラウンド スレッドで:
dispatch_queue_t fetchQ = dispatch_queue_create("syncing list", NULL);
dispatch_async(fetchQ, ^ // *********** BACKGROUND THREAD ***********
{
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *backgroundMOC2;
backgroundMOC2=[[NSManagedObjectContext alloc] init];
[backgroundMOC2 setPersistentStoreCoordinator:delegate.mainManagedObjectContext.persistentStoreCoordinator];
[backgroundMOC2 setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[delegate.mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[[NSNotificationCenter defaultCenter] addObserver:delegate.mainManagedObjectContext selector:@selector(mergeChangesFromContextDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2];
** pseudo-code:
perform fetch request from CD
submit data to server with POST request (synchronously)
retrieve JSON reply from server
update what's needed in CD objects
** end of pseudo code
[backgroundMOC2 save:nil];
[[NSNotificationCenter defaultCenter] removeObserver:delegate.mainManagedObjectContext name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2];
});
dispatch_release(fetchQ);
すべての種類のマージ ポリシー定数を試しましたが、役に立ちませんでした。
私はこれを取得していますが、ファイルは保存されていません:
conflictList = ( "NSMergeConflict (0x1a9ee1e0) for NSManagedObject (0x119aea80) with objectID '0x9dcec90 ' with oldVersion = 10 and newVersion = 11 and old object snapshot = {\n displayName = \"\";\n machineName = KIYGRDRTTDVLTQB;\n note = \"\";\n 製品 = \"0x11967ab0 \";\n 公開 = 1;\n 公開 = 1;\n 数量 = 3;\n registeredTo = \"\";\n registeredToEmail = \"\ ";\n registeredToNote = \"\";\n status = \"ON REGISTRY\";\n upDate = \"2013-03-07 10:22:01 +0000\";\n wishList = \"\ ";\n} および新しいキャッシュ行 = {\n displayName = \"\";\n machineName = KIYGRDRTTDVLTQB;\n note = \"\";\n product = \"0x1a9ee3d0 \";\n public = 1 ;\n 公開 = 1;\n 数量 = 3;\n registeredTo = \"\";\n registeredToEmail = \"\";\n registeredToNote = \"\";\n status = \"登録中\";\n upDate = \" 2013-03-07 10:22:03 +0000\";\n ウィッシュリスト = \"\";\n}" ); }
ところで、古いオブジェクトと新しいオブジェクトの唯一の違いは、「製品」へのポインタです。これは私の問題でしょうか?
別の考えられる手がかりは、これが追加された新しいオブジェクトでのみ発生し、バックグラウンド同期が行われた後にのみ発生するという事実です。アプリを停止してリロード (永続ストアのリロード) すると、既存のオブジェクトを問題なく編集し、何回でも問題なく同期できます。
みんなありがとう