2013-03-07 6 views
8

OK、これは私をナットにしています。NSMergeConflict(2つのスレッド) - マージポリシーを設定しても解決しない

私はUImanageddocumentを使って2つのスレッドを持っています.1つはメインコンテキストでユーザーが選択し、もう1つは独自のmocを持つバックグラウンドスレッドがタイムスタンプに従ってサーバーとデータを同期させます。 1.今から、再度、同じオブジェクトを変更しようとする背景 4からメインコンテキストに背景 3.保存中 2.同期をオブジェクトを追加します:Iとき

すべてはしかし、うまく動作しているようですメインコンテキスト - メインスレッド

は、私はうまくいけば、誰かが私を啓発することができ、私はコンテキストを初期化する方法をお見せするために、無関係なコードの多くを除く鉱山のいくつかのコードを含めるつもりですNSMergeConflict

を取得します。私はコアデータがこれらの分野では難しいことを知っています。

(applicationdidfinishloadingwithoptions中)メインスレッドで

:私はマージのすべてのタイプを試してみました

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); 

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); 
     }]; 
} 

そして、バックグラウンドスレッドでポリシー定数は役に立たない。

私はこれを取得していますし、ファイルが保存されていません。

conflictList =( 「NSMergeConflict(0x1a9ee1e0)NSManagedObject(0x119aea80)のためoldVersion = 10とNEWVERSION = 11とオブジェクトID '0x9dcec90' で\ n "=" "\ n" "パブリック= 1; \ nパブリッシュ= \ n ""レジストリに登録されていない場合は、\ n " \ n wishList = \ "\"; \ n}と新しいキャッシュ行= {\ n displayName = \ "\"; \ n machineName = KIYGRDRTTDVLTQB; \ "2013-03-07 10:22:01 +0000 \"; \ n注= \ "\"; \ n製品= \ "0x1a9ee3d0 \"; \ nパブ\ n ""登録済み= \ "\"; \ n登録済み= \ "\"登録済み\ n "=" REGISTRY \ "; \ n upDate = \" 2013-03-07 10:22:03 +0000 \ "; \ n wishList = \" \ "; \ n}" ); }

私が古いオブジェクトと新しいオブジェクトの間に見る唯一の違いは、「製品」へのポインタです。 これは私の問題かもしれませんか?

別の可能性のある手掛かりは、新しいオブジェクトが追加された場合にのみ発生し、バックグラウンドでの同期が行われた後に発生するということです。 アプリケーションを停止して再ロード(永続ストアをリロード)しても、既存のオブジェクトを問題なく編集でき、問題なく何度でも同期することができます。

みんなありがとう

答えて

19

OKの友人、この上で私の心を壊す月後

- ソリューション、と私は推測しているだろう何があります。私は実際にアップル社のサポート事件を開き、彼らはこれを解決しました。

は、だからここに行く:

メイン管理オブジェクトコンテキストのマージポリシーを設定し、parentContextと呼ばれるプロパティがあります。このプロパティはドキュメントが不足しているため、このプロパティが何であるかはまだ分かりません。しかし、これは間違いなく私の問題を解決します。 私のワークフローでは、NSManagedDocumentを作成し、そこからコンテキストを抽出することを考慮してください。私はほとんどの人がそれを逆にしていると思います(ほとんどが管理文書を使用しません)。

私が今使っ

代わりの

[self.mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 

NSManagedObjectContext *parentContext = delegate.mainManagedObjectContext.parentContext; 
    [parentContext performBlockAndWait:^{ 
     [parentContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    }]; 

ブロック事は、これは適切なスレッドで実行され、重要なことは、マージポリシーを設定することであることを確認するための予防策です目的のコンテキストのparentContextに設定します。

2つの大きなブーを追加する必要があります。 1.私は、NSManagedDocumentを使用するために少し古くなっています。 2.フィールドにはほとんどドキュメントがないので、Appleには大きな声をかけます。私はManagedObjectContextsについて何週間も読んでいましたが、今日はparentContextプロパティーとの最初の知り合いでした。

+0

こんにちは@llan lewin、このリンクをご覧くださいhttp://stackoverflow.com/questions/19443853/nsmergeconflict-for-nsmanagedobject-with-single-managedobjectcontext – Ranjit

+0

まずは、ありがとうございます!これは間違いなく私の問題を解決します。親コンテキストについては、https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingCoreDataWithiCloudPG.pdf(セクション:管理対象ドキュメントの管理オブジェクトコンテキストの使用)を参照してください。 –

+0

こんにちはIlan、あなたの答えでは、このアプローチ(すなわち、performBlockAndWaitのマージポリシーを設定する)は、NSManagedDocumentを作成してコンテキストを取得するときに便利です。私はこのワークフローを使用していません。これを自分のワークフローにも追加する必要がありますか?または他の方法がありますか? – Arun

関連する問題