0

Concurrency with Core Data Guide에 따르면 스레드가 분리 되었기 때문에 앱이 저장이 완료되기 전에 종료 될 수 있기 때문에 NSManagedObjectContext를 백그라운드 스레드에 저장하면 안됩니다.백그라운드 큐에 임시 관리 대상 개체 컨텍스트 저장

내가 제대로 이해 해요 경우, 즉 이런 일이 잘못된 것을 의미

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
    NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [tempContext setParentContext:[[MyDataManager sharedInstance] mainContext]; 
    [tempContext performBlockAndWait:^{ 
     //Do some processing 
     NSError* error; 
     [tempContext save:&error]; 
    }]; 
}); 

나의 첫번째 본능 그냥 끝났어 주 큐의 컨텍스트를 저장하는 것입니다,하지만 managedObjectContexts는 스레드로되어 있습니다 안전한. 문제를 해결하거나 더 나은 해결책이있는 다음과 같은 것이 있습니까? 먼저

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
    NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [tempContext setParentContext:[[MyDataManager sharedInstance] mainContext]; 
    [tempContext performBlockAndWait:^{ 
     //Do some processing 
    }]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [tempContext performBlockAndWait:^{ 
      NSError* error; 
      [tempContext save:&error]; 
     }]; 
    }); 
}); 

답변

1

:

첫 번째 예에서 :
[context save:...]는 문맥의 performBlockAndWait: 블록에서 수행해야합니다. 당신이 배경 컨텍스트를 사용하는 경우
또한, 이미 파견에 대한 GCD를 사용하는대로 당신은 단순히 그 performBlock: 메서드를 호출 할 수있다, 그래서 같은 모양 : 둘째

NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
[tempContext setParentContext:[[MyDataManager sharedInstance] mainContext]; 
[tempContext performBlock:^{ 
    //Do some processing 
    NSError* error; 
    [tempContext save:&error]; 
}]; 

:

"백그라운드 스레드에 저장하는 중 오류가 발생하기 쉽습니다." (알고 있고 이해할 수 있음) 의미 :
백그라운드에서 저장할 수는 있지만 호출 된 저장이 완료 될 때까지 실행되지 않을 수도 있습니다. 응용 프로그램을 종료합니다 (데이터베이스는 여전히 유효하지만, 또는 부분 - 저장 전 상태로 롤백 될 수있다).
==>
백그라운드 저장을 사용하는 경우 두 번의 응용 프로그램 실행 사이에 저장 작업이 완료되었다고 가정하지 마십시오.

세 번째 (단지 강조하기 위해) :
예기치 않은 동작으로 이어질 것입니다>
두 번째 예 performBlock: 또는 performBlockAndWait:
==없이 민간 큐 컨텍스트를 사용하지 마십시오

+0

performBlock에 저장 부르심 확인 의미가 있지만 응용 프로그램이 종료되기 전에 백그라운드 저장이 완전히 완료되도록하는 방법이 있습니까? – adamF

+0

두 번째 요점에서 언급했듯이. 이것이 메인 스레드 저장과 백그라운드 저장의 차이점입니다. 저장해야하는 중요한 정보가있는 경우 주 스레드에서 저장하십시오. –

+0

고마워,하지만 내 원래의 질문은 어떻게 실제로 그것을 할 수 있습니까? 내 두 번째 예가 예기치 않은 행동으로 이어질 것이라고하셨습니까? 그것은 performBlock을 사용하지 않았기 때문입니까 아니면 기본 스레드에서 실행되는 개인 대기열 컨텍스트이기 때문에입니까? 내 편집 된 질문을 참조하십시오. 메인 쓰레드에 저장할 올바른 방법은 무엇입니까? – adamF

관련 문제