2013-04-23 5 views
3

새로운 주제는 아니지만 제 문제에 대한 명확한 답을 찾지 못했습니다.코어 데이터 및 다중 스레드 프로그래밍

"Book"이 포함 된 핵심 데이터 모델이있는 프로젝트를 진행 중입니다. 따라서 네트워크를 통해 json 데이터를 다운로드 할 때 이러한 북 모델을 내 핵심 데이터 (백그라운드 스레드에서 UI를 차단하지 않도록)에 저장 한 다음이 컨트롤러 모델과로드 테이블에이 Book 모델을 전달하려고합니다.

그러나 Apple의 Core Data Reference를 배웠을 때 혼란스러워졌습니다. 이 문서에서는 컨텍스트간에 관리 객체를 전달하면 안된다고 말합니다. 하지만 두 가지 컨텍스트가 있습니다. 하나는 주 스레드 용이고 다른 하나는 배경 스레드 용이며 다운로드, 저장 및 현재 업데이트 된 데이터 가져 오기에 사용됩니다. 그래서 내가해야 할 일은 백그라운드에서 관리 대상 객체 ID를 가져 와서 이러한 ID를 주 스레드의 컨텍스트에 전달한 다음 주 스레드에서이 ID로 관리 객체를 가져 오는 것입니다.

여기에 문제가 있습니다. 메인 스레드 블록 UI에서 ID로 관리 객체를 가져 오겠습니까? 메인 스레드에서 해당 ID로 관리 객체를 가져올 때 SQLite에 액세스합니까? 그리고 이러한 가져온 관리 객체 중 일부가 잘못 되었다면 이는 내가 소유권을 얻고 자한다면 IO를 수행 할 수 있음을 의미합니다. 여전히 UI가 차단되는 것 같습니다.

코어 데이터를 사용하여 백그라운드에서 데이터를 가져오고 이러한 데이터를 UI를 차단하지 않고 주 스레드 (UI 작업이 주 스레드에 있어야 함)에 표시하는 실제적인 패턴은 무엇입니까?

도움 주셔서 감사합니다.


은 다시 생각 :

사실 모든 해답은 내 문제가 해결되지. 그러나 핵심 데이터에서 다중 스레드 프로그래밍을 사용해야 할 때 고려해야 할 사항이 있습니다. 대부분의 경우, 핵심 데이터를 그대로 사용하는 것이 효율적일 수 있습니다. 나는 메인 스레드에서 코어 데이터 연산의 비용을 과대 평가했다.

그러나 아직도, 누군가가 배경에서 가져 오기를 수행하고 메인 스레드에 표시하는 실용적인 패턴을 추천하기를 바랍니다. 나는 그것을 감사 할 것이다!

답변

1

그것은 마법력에 갱신/삽입 작업을 수행해야합니다.

백그라운드 스레드에서 모든 다운로드를 수행 한 다음 주 스레드에 개체를 삽입하는 것이 가장 효과적이라는 것을 알게되었습니다. 30 분마다 단지 수백 건의 업데이트 만 있다면 UI 성능에 영향을 미치지 않아도됩니다. 내 경험에 비추어 볼 때, 강력하고 간단한 것처럼 메인 스레드에 미치는 영향이 훨씬 큽니다. 컨텍스트 동기화에 신경 쓸 필요가 없으며 올바른 스레드에서 올바른 개체를 사용하는지 확인해야합니다.

+0

이것이 도움이된다고 생각합니다. 내 경우에는 사용자가 더 많은 정보를로드 할 때 50 권의 책을 다운로드하고 핵심 데이터를 삽입하고 모든 책을 내 UI에 표시합니다. 나는 코어 데이터 50 항목은 단지 작은 양의 데이터라고 생각합니다. 그러나, 사용자가 처음 앱을 실행할 때 모든 책을 다운로드한다면, 메인 스 레드에서이 모든 작업을 매우 무거울 수도 있습니다. –

0

당신은 백그라운드 스레드에서 다운로드하여 데이터를 수행 한 다음 데이터베이스에 어떻게 많은 삽입에 메인 쓰레드

+1

이 답변은 OP에 도움이되지 않습니다. 좀 더 자세한 정보를 제공 할 수 있습니까? – Anupdas

+0

그래서 메인 스레드에서 업데이트하고 삽입하면 UI가 차단 될 수 있습니다. 또한, 내가 걱정하는 것은 실제로 주 스레드에서 가져 오는 것입니다. 주 스레드에서 가져 오기를 수행하면 UI가 차단됩니다. 하지만 백그라운드에서 가져 와서 기본 스레드에 ID를 전달한 다음 주 스레드에서 이러한 ID를 사용하여 관리되는 개체를 가져 오면 여전히 UI가 차단됩니까 ?? –

1

먼저 간단하게 유지하십시오. 가지고 있지 않은 문제를 해결하기 위해 저글링 컨텍스트를 원하지는 마십시오. 네, 메인 스레드에서 가져 오기 UI를 차단합니다,하지만 당신이 진짜 하드웨어에서 실제 문제가 발견하지 않는 한, 당신은 그것을 무시할 수 있습니다. 페치가 너무 무거워서 상당한 시간이 걸리면 프로필을 작성하고 최적화하십시오. 핵심 데이터 및 계측기에 대한 WWDC '12 비디오와 뛰어난 마커스 자라 book을 살펴보십시오.

0
이 당신을 도울하지만 내 여자 친구는 시도를 블로그 멋진 코코아에서이 블로그 항목 이상을 줄 것인지 모르겠어요

: Core Data and Threads, Without the Headache

그것은이 문제에 대한 몇 가지 방법을 설명하고 또한 UI 취급 및 주 스레드 질문.

+1

게시물이 좋은 디자인을 제공하지만 게시물은 오래되었지만 대부분의 내용은 새로운 하위/상위 MOC 모델과 함께 iOS5에서 구현되었습니다. 단지 ios6을 시작하는 데 유용하다고 말합니다. –

+0

의견을 말하면서 유용 할 것입니다. 자체 콘텐츠가 없습니다. – cHao

3

귀하의 경우, 3 개의 MOC를 사용합니다.

NSManagedObjectContext *worker = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyTyep]; 
worker.persistentStoreCoordinator = // your PSC 
NSManagedObjectContext *main = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
main.parentContext = worker; 

그런 다음 백그라운드 작업을 수행 할 때마다 백그라운드 MOC를 기본 MOC의 하위로 생성하십시오.

NSManagedObjectContext *background = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
background.parentContext = main; 

상황을 저장하면 한 단계 만 저장됩니다. 따라서 백그라운드 컨텍스트를 저장하면 변경 사항이 자동으로 주 컨텍스트로 푸시됩니다.

언제든지 주 컨텍스트를 저장할 수 있지만 어느 시점에서는 작업자 컨텍스트를 저장해야합니다. UIManagedDocument은 자동으로 주/작업자 저장 상호 작용을 처리합니다 (그러나 사용시에는 일부 통제를 포기합니다).

다른 이점은 실제 IO 작업이 주 스레드에서 발생하지 않는다는 것입니다.

+0

답변 해 주셔서 감사합니다. 당신의 대답에 2 가지 질문이 있습니다. 먼저, 가져 오기 작업을 수행하는 데 사용해야하는 컨텍스트와 그 결과를 표시하는 방법입니다. 둘째, "작업자"컨텍스트의 역할은 무엇입니까? @Jody –

+0

'NSFetchedResultsController'를 주 MOC에 연결하십시오. UI 스레드를 원할 때 메인 스레드에서 실행됩니다. 배경 컨텍스트는 네트워크에서 다운로드 한 항목을 추가하는 데 사용됩니다. 작업자 컨텍스트는 실제 IO 작업이 주 스레드가 아닌 백그라운드 스레드에서 수행되도록하기위한 것입니다. –

관련 문제