2011-12-14 8 views
0

メインスレッドで使用されるmainContextがあります。 mainContextが作成されると、NSManagedObjectContextDidSaveNotification通知用のNotificationCenterにオブザーバを追加します。代替スレッドからの変更で他のコンテキストを更新する方法

新しいスレッドが作成され、NSManagedObjectContextが必要な場合は、新しいスレッドでコンテキストを作成し、その情報を保存します。新しいスレッドのコンテキストへの変更を保存します。

通知ハンドラが呼び出され、スレッドのすべてのコンテキストの変更がマージされます。影響のある各コンテキストのマージポリシーがあり、適切なスレッドの変更をマージしています。

私はまだ「楽観的なロック失敗」をランダムに取得しています。私が紛失しているものはありますか?

- (void)contextChanged:(NSNotification *)notif 
{ 

    //gets called from the thread(where the context was) that made the changes 
    //iterate over all contexts and mergeChanges on their thread 
    NSLog(@"NotifContext %@ %p", [notif object], [NSThread currentThread]); 

    //always check the main 
    if([notif object] != [self mainContext]){ 
     NSLog(@"merge with main %@", [self mainContext]); 
     [[self mainContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notif waitUntilDone:NO]; 
    } 


    //check alternate cotexts and merge changes on their threads 
    NSDictionary *altContexts = [self.altContexts copy]; 
    for(NSString *threadAddress in altContexts){ 
     NSDictionary *info = [altContexts objectForKey:threadAddress]; 
     NSManagedObjectContext *context = [info objectForKey:@"context"]; 
     if(context != NULL && [notif object] != context){ 
      NSLog(@"merge with %@", context); 
      NSThread *thread = [info objectForKey:@"thread"]; 
      [context performSelector:@selector(mergeChangesFromContextDidSaveNotification:) onThread:thread withObject:notif waitUntilDone:NO]; 
     }else{ 
      NSLog(@"not with %@", context); 
     } 
    } 
    [altContexts release]; 
} 

答えて

0
waitUntilDone:NO //should have been YES 

私はこれを見落とし。私はそれが完了するまで待つつもりだった。それ以外の場合は、保存が発生し(スレッド2)、通知がディスパッチされ、contextChanged:ハンドラがトリガされ、他のコンテキストにスレッド(スレッド1)の変更をマージするよう指示され、スレッド2はスレッド1実際には保存されます。