1

내가이멀티 스레드 코어 데이터는 - NSManagedObject는 제목으로

managedContext = [[NSManagedObjectContext alloc] init]; 
[managedContext setUndoManager:nil]; 

[managedContext setPersistentStoreCoordinator: [[DataManager sharedManager] persistentStoreCoordinator]]; 

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self 
     selector:@selector(mergeChanges:) 
      name:NSManagedObjectContextDidSaveNotification 
      object:managedContext]; 


NSMutableArray *returnSource = [[self parseDocument:doc] retain]; 


[managedContext save:&error]; 

if (error) { 
    NSLog(@"saving error in datafeed"); 
} 

[managedContext reset]; 

[self performSelectorOnMainThread:@selector(parseCompleteWithSource:) withObject:returnSource waitUntilDone:YES]; 
을하고있어 내 백그라운드 스레드에서 다른 배경 스레드에서 객체 (XML 구문 분석)

로 채워집니다 핵심 데이터 응용 프로그램 작업 메신저를 제안 무효화

병합 방법은 다음과 같습니다

NSManagedObjectContext *mainContext = [[DataManager sharedManager] managedObjectContext]; 

// Merge changes into the main context on the main thread 
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) 
           withObject:notification 
          waitUntilDone:YES]; 

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

나는 병합이 성공하지만 난이 jQuery과에 표시 원하는대로 항상 나에게 t을 알려줍니다 생각 내 객체가 무효화 모자가 예상되는 때문에 그게 전부 내가를 업데이트 할 완료 내가 뭘 XML을 구문 분석 백그라운드에서 현재 데이터베이스에있는 항목을 표시 할 일은 원하는 경우

[managedContext reset]; 

새로운/업데이트 된 개체가있는 UITableView. 어떻게해야합니까, 나는 "컨텍스트"를 어떻게 든 다른 개체를 "업데이트"할 수 있습니까? 그렇지 않으면 병합이 제대로 작동하지 않습니까?

Main ObjectContext에서 특정 항목을 정의해야합니까? 나는 행운없이 다른 mergepolicies를 시도했다.

희망을 보내 주시면 감사하겠습니다.

+0

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html –

답변

3

귀하의 문제는 returnSource 배열의 내용이라고 생각합니다. 이것이 NSManagedObject 인스턴스의 묶음이라면 백그라운드 스레드 컨텍스트에 의해 백그라운드 스레드에 작성되었을 것입니다.

-[NSManagedObjectContext reset]으로 전화하면 문맥을 명시 적으로 알려주므로 무효화됩니다. 하지만 큰 문제는 아닙니다.

그런 다음 배열을 주 스레드로 보내고 NSManagedObject 개의 인스턴스를 스레드 테두리에 전달하고 컨텍스트 간에는 큰 no-no를 전달합니다. 당신이해야 할 일은

은 다음과 같습니다

  1. NSManagedObjectNSManagedObjectID의 배열을 만듭니다.
  2. 스레드 경계를 통해 개체 ID 배열을 보냅니다.
  3. 콘텍스트가있는 새 스레드의 관리 객체 ID에서 NSManagedObject으로 배열을 다시 만듭니다.

나는 (IT 일반을, 당신이 뭔가를 쓰기 세 번째) 세 의 규칙에 따라 약간의 코어 데이터 도우미를 만들었습니다.

가장 중요한 것은 각 스레드, 알림 처리 및 모든 정크에 대해 서로 다른 관리되는 개체 컨텍스트를 관리하는 복잡성을 감추었습니다. 대신 스레드 로컬 컨텍스트의 개념을 도입했습니다. 기본적으로 느슨하게 만들어진 NSManagedObjectContext 인스턴스는 현재 스레드가 종료 될 때 업데이트 및 정리를 자동으로 등록합니다.

정상적인 사용의 경우 :

NSManagedObjectCotext* context = [NSManagedObjectCotext threadLocalContext]; 
// Do your stuff!! 
NSError* error = nil; 
if (![context saveWithFailureOption:NSManagedObjectContextCWSaveFailureOptionThreadDefault 
           error:&error]) 
{ 
    // Handle error. 
} 

전체 소스 코드, 코어 데이터에서 그것을 apple.com에서 뉴스 RSS를 파싱 및 저장에 대한 샘플 응용 프로그램을 포함하여, 여기에 있습니다 : https://github.com/jayway/CWCoreData.

+0

-1 코드가 유용 할 수도 있지만 실제로이 특정 문제에 대한 대답은 아닙니다. – TechZen

+0

@TechZen - 당신이 옳아서 제 대답이 확장되었습니다. – PeyloW

+0

안녕하세요! 감사합니다. 나는이 하나를 알아 냈고, 당신이 여기서 묘사 한 것을 정확히했습니다. :) – Patrick

1

배경 스레드와 함께 어쨌든 사라 지므로 어떤 경우에도 다시 사용하지 않기 때문에 배경 컨텍스트에서 reset을 호출 할 이유가 없습니다. 컨텍스트가 이전 단계를 잊어 버리도록하려면 일반적으로 실행 취소 관리와 함께 reset을 사용합니다.

여기서 중요한 문제는 백그라운드 스레드가 자신이 만든 관리 대상 개체 컨텍스트에서 알림을 받도록 구성되어 있다는 것입니다. 그것은 오히려 무의미합니다.

대신 앞쪽 스레드에서 tableview 컨트롤러를 등록해야 배경 스레드의 컨텍스트에서 NSManagedObjectContextDidSaveNotification을 수신 할 수 있습니다. 이렇게하면 백그라운드 컨텍스트가 저장 될 때 front/main 컨텍스트가 새로운 데이터로 업데이트되어 tableview 업데이트를 트리거합니다.