2011-06-10 2 views
3

코어 데이터 객체에 대해 몇 가지 작업을 수행하는 백그라운드 스레드가 있습니다. 다음과 같이 내가 컨텍스트를 얻을 :코어 데이터 및 멀티 스레딩 (및 더 재미있게 만들기위한 바인딩)

- (id)_managedObjectContextForThread; 
{  
    NSManagedObjectContext * newContext = [[[NSThread currentThread] threadDictionary] valueForKey:@"managedObjectContext"]; 
    if(newContext) return newContext; 

    newContext = [[NSManagedObjectContext alloc] init]; 
    [newContext setPersistentStoreCoordinator:[[[NSApplication sharedApplication] delegate] persistentStoreCoordinator]]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(_mergeChangesFromManagedObjectContext:) 
              name:NSManagedObjectContextDidSaveNotification 
              object:newContext]; 

    [[[NSThread currentThread] threadDictionary] setValue:newContext forKey:@"managedObjectContext"]; 
    return newContext; 
} 

그때 나는 일부 개체를 가져, 그것들을 수정하고 컨텍스트를 저장합니다

- (void) saveContext:(NSManagedObjectContext*)context { 
    NSError *error = nil; 
    if (![context save:&error]) { 
     [[NSApplication sharedApplication] presentError:error]; 
    } 
} 

- (void)_mergeChangesFromManagedObjectContext:(NSNotification*)notification; 
{ 
    [[[[NSApplication sharedApplication] delegate] managedObjectContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) 
                        withObject:notification 
                       waitUntilDone:YES]; 
} 

.. 나중에 내가 관찰자를 제거합니다. 이것은 주요 부분에 대해 작동합니다. 그러나 일부 속성은 병합 될 때 업데이트되지 않습니다. 전에 업데이트되지 않은 속성은 업데이트됩니다. 가치가있는 것들은 그대로 유지됩니다. 주요 상황에

[newContext setMergePolicy:NSOverwriteMergePolicy]; 

(다른 병합 정책을) 그러나 그것은 작동하지 않았다 :

나는 시도

P

당신의 도움을 주셔서 감사합니다.

참고 : 값을 NSTableView에 바인딩했습니다. 병합 후에 기록합니다. nil 값 속성은 정상적으로 작동하는 것 같습니다.

답변

5

알림을 위해 두 컨텍스트를 어떻게 등록하고 있습니까? 콜백을

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 

[nc addObserver:self 
     selector:@selector(backgroundContextDidSave:) 
      name:NSManagedObjectContextDidSaveNotification 
     object:backgroundMOC]; 

[nc addObserver:self 
     selector:@selector(mainContextDidSave:) 
      name:NSManagedObjectContextDidSaveNotification 
     object:mainMOC]; 

및 구현 : 당신은 같은 것을 할 필요가

// merge changes in background thread if main context changes 
- (void)mainContextDidSave:(NSNotification *)notification 
{ 
    SEL selector = @selector(mergeChangesFromContextDidSaveNotification:); 
    [backgroundMOC performSelector:selector onThread:background_thread withObject:notification waitUntilDone:NO]; 
} 


// merge changes in main thread if background context changes 
- (void)backgroundContextDidSave:(NSNotification *)notification 
{ 
    if ([NSThread isMainThread]) { 
     [mainMOC mergeChangesFromContextDidSaveNotification:notification]; 
    } 
    else { 
     [self performSelectorOnMainThread:@selector(backgroundContextDidSave:) withObject:notification waitUntilDone:NO]; 
    } 
} 
+1

가 나는 NSOperation에 걸쳐 모두 이동도 주요 상황을 듣고 그것을 시도. 작동하지 않습니까? P 그렇다면 관리 대상 객체 ID를 수정 스레드에 제공하는 기본 스레드에서 값을 업데이트하는 줄을 발견했습니다. 그 전에 컨텍스트를 저장하지 않았습니다. 이제 mofifing 스레드 전에 컨텍스트를 저장하고 모두 괜찮습니다. 도와 줘서 고마워. – david