2014-01-13 3 views
1

현재 멀티 스레드 환경에서 코어 데이터를 사용하는 방법을 배우고 있습니다. 읽고에 대한/업데이트를 생성/삭제 작업을 NSPrivateQueueConcurrencyType와 자식 NSManagedObjectContext에 대한 NSMainQueueConcurrencyType와 메인 NSManagedObjectContext : NSPrivateQueueConcurrencyType을 사용하여 NSManagedObjectContext 저장

은 그래서 저는 두 NSManagedObjectContext와 작은 프로젝트를 만들었습니다.

종종 NSPrivateQueueConcurrencyTypeNSManagedObjectContext 지금처럼 performBlock:을 통해 수행되어야 절약이 말했다되었습니다

performBlock:가 생략 된 경우, 어떻게 그렇게 좋아
[context performBlock:^ 
{ 
    Book *mutableBook = [self getMutableVersionOfBook:book]; 

    [context deleteObject:mutableBook]; 

    [context save:nil]; 
}]; 

:

Book *mutableBook = [self getMutableVersionOfBook:book]; 

[context deleteObject:mutableBook]; 

[context save:nil]; 

가합니까 저장이 호출 된 스레드에서 저장이 발생합니까? performBlock:을 사용하지 않으면 어떻게됩니까?

+0

시도하면 어떻게됩니까? – Abizern

+0

@Abizem 데이터를 저장합니다. 나는 데이터가 어떤 식으로 저장되는지, 그리고 왜 이것이 권장 접근법이 아닌지 궁금하다. – MrJre

+0

BooL * mutableBook 라인과 deleteObject 라인 다음에 중단 점을 놓고 새 스레드가 생성되었는지 확인하십시오 (Xcode -> 왼쪽면 -> 여섯 번째 탭 -> CPU-> 아래 스레드 참조).이것이 새 스레드에서 발생하는지 여부를 알 수 있습니다. – santhu

답변

4

개인 큐 MOC는 -performBlock: 또는 -performBlockAndWait:을 통해서만 접촉해야합니다. 다른 방법으로 터치하면 Core Data의 스레드 경계 규칙을 위반하고 결국 데이터 손상이 발생합니다.

스레드 경계를 위반하는 것이 응용 프로그램 수준 오류이기 때문에 상황에 따라 응용 프로그램에 충돌이 발생할 수 있습니다. 애플은 그 충돌을 여러 번 돌 렸고 지금은 충돌 상태 일 수도 있고 아닐 수도있다. 제 의견으로는 언제나의 충돌 상태 여야합니다.

일반적으로 개인 MOC를 사용하는 대신 주 MOC의 하위 항목으로 스레드 제한 MOC를 사용하는 것이 좋습니다. 비공개 MOC가 유용하고 유용하지만 모든 작업의 ​​구조는 블록에 있어야하며 결과 블록 인 NSManagedObject에 액세스 할 수 없다는 점을 제외하고는 해당 블록이 제한적입니다. 작업을 대기열로 돌리고 스레드에 한정된 MOC를 해당 대기열에 생성 한 다음 블록으로 다이빙을 끊임없이 수행하는 것보다 더 깨끗한 코드를 생성하는 것이 더 좋습니다 (또는 거대한 비 maintanable 블록 생성).

마지막으로 nil-save:에게 전달 중입니다. 절대로하지 마십시오. 당신은 그렇게 할 때 잠재적 인 문제를 숨기고 있습니다. "그것은 단지 예"라 할지라도, 그것은 끔찍한 버릇이며, 즉시 깨뜨려 야합니다. 예제 코드에서도 NSError을 전달하고 오류를 확인하십시오. NSLog에게 결과를 전달하더라도 최소한 놀라움은 피할 수 있습니다.

+1

IMO가'NSError ** '인수에'nil'을 넘기는 것은 잘못된 것입니다. 그것은 포인터 인자이므로, 여러분이 진정으로 오류에 대해 신경 쓰지 않는 몇몇 경우에 대해서'NULL'은 옳은 일이 될 것입니다. – alastair

+0

내가 말할 수있는 한, 자식 MOC는 여전히 Mavericks에서 심각하게 손상되어있다. (새로 삽입 된 오브젝트 사이의 관계는 저장을 중단한다 .personanidIDsForObjects는 저장하기 전에 문제를 해결 하나 가장 이상한 말은 성가시다.) 당신은 정말로 그들을 사용하는 것이 좋습니다? –

+0

@fabricetruillotdechambrier : 짧은 대답; 예. 그들은 쉽게 상상할 수 있습니다. 가장자리는 다른 옵션보다 덜 날카 롭습니다. 그들은 가장 실적이 좋은가요? 아니지만 그들은 멀티 스레딩 CD를 수행하는 명확한 방법입니다. 다른 솔루션에 익숙하거나 안성맞춤이라면 Core Data를 시작하는 개발자에게 권장하지 않습니다. –

1

저장은 아마도 호출 된 스레드에서 발생합니다. 결과는 무엇입니까? 우리는 구현을 모르기 때문에 추측 만 할 수 있습니다. 때로는 관리 컨텍스트 및 관리 대상 객체의 잘못된 사용으로 인해 실제로 이상한 동작이 발생할 수 있으며 스레딩 실수로 인한 것일 수도 있습니다.

컨텍스트 및 관리 객체가있는 모든 작업은 생성 된 스레드 또는 대기열에서 수행해야합니다. 기본적으로 전통적인 컨텍스트와 개인 큐 동시성 유형이있는 컨텍스트에서는 동일합니다. 후자는 대기열을 작성하고 항상 대기열을 유지합니다.