2012-05-03 2 views
3

사용자가 명시 적으로 동기화 버튼을 누른 후 웹에서 잠재적으로 많은 양의 데이터를 가져 오는 앱이 있으며 핵심 데이터를 사용하여 해당 데이터를 저장합니다. 피드백이 표시되기 때문에 사용자가 나머지 앱과 상호 작용하는 것을 원하지 않으므로 동기화 버튼을 누르면 모달 대화 상자가 표시됩니다. 즉시 작업을 수행하기 때문에 작업은 viewDidAppear 메서드에서 실행됩니다. 나는 이것이 눈살을 찌푸린다고 확신한다.코어 데이터를 사용하는 장기 실행 포 그라운드 작업의 모범 사례?

지금 접근 방식에 문제의 무리가 있습니다

  • 모든 메인 스레드에서 발생합니다. 사용자의 종류는 피드백을받습니다. 활동 표시기가 계속 움직이지만 진행 상황을 나타내거나 중간 메시지를 표시 할 수있는 방법이 없기 때문입니다. 이것은 일을하는 올바른 방법이 아닙니다.
    • 하지만 핵심 데이터를 사용할 때는 모든 것이 주 스레드를 사용해야하므로 다른 스레드로 작업을 중단하는 것은 간단하지 않은 것처럼 보입니다.
  • 앱이 백그라운드 상태 (사용자가 홈 버튼을 누르거나 iPad가 잠자기)에 들어가면 게임이 종료되어 작업이 종료됩니다. 이것이 왜 그런지 문서에서 분명합니다.
    • "배경을 입력하려고합니다."사용자가 처리 할 수있는 이벤트가 있음을 알고 있지만 파일 다운로드 중간에 코드 실행을 다른 곳으로 이동할 수있는 것처럼 아닙니다. 내가 사용하는 모든 솔루션은 백그라운드로의 전환 전후에 동일한 방식으로 실행되는 지속적인 동작이어야합니다.
    • 사용자가 우려하는 한 포어 그라운드에서 작업을 실행하고 싶습니다. 이 작업이 진행되는 동안 앱의 다른 부분과 상호 작용하는 것은 의미가 없습니다.

나는 이것에 애플 문서를 읽고있다, 그러나 나는 요구의 특정 조합에 더 간결한 안내를 찾는 희망이 부탁 해요. 감사.

+0

메인 스레드가 필요한 코어 데이터에 관한 진술이 사실이 아닙니다. 다음의 동시성 섹션을 읽어보십시오 : https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html –

+0

@T Reddy 네 말이 맞아. 내 문은 주 스레드의 관리되는 개체 컨텍스트를 작업자 스레드로 전달하려고하는 경우에만 해당됩니다. 작업자 스레드에서 새로운 관리 객체 컨텍스트를 만드는 경우 지원됩니다 (기본 스레드의 관리 객체 컨텍스트에서 변경된 작업자 컨텍스트를 알 수 있도록해야합니다). –

+0

컨텍스트는 물론 관리 대상 개체가 스레드 경계를 넘을 수 없습니다. 이 관리 객체 래퍼를 사용하여 Core Data 문서에 설명 된대로 스레딩 요구 사항을 용이하게했습니다. https://github.com/chriscdn/RHManagedObject –

답변

2

정말 주 스레드를 고정 시켜서는 안됩니다. 특정 UI 작업을 "금지"할 수 있습니다.

아이처럼 별도의 컨텍스트를 만들고 거기에서 모든 작업을 수행하십시오. (또는 특정 간격)이 완료되면 주요 상황에 대한 컨텍스트를 저장하고 일부 UI 업데이트 상호 작용 ... 어쩌면 진행 표시 줄이나 뭐 ... 할 메인 스레드를 통지 일의

NSManagedContext *backgroundContext = [NSManagedContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
backgroudContext.parentContext = [self mainManagedObjectContext]; 
[backgroundContext performBlock:^{ 
    // This block is running in a background thread. 
    // Go get your data from the web 

    // Call this to push data to the main MOC (either at end, or at intervals) 
    [backgroundContext save:&error]; 

    // When you want to do something on the main thread... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // This block is running on the main queue... I can do anything with the UI... 
    }]; 
}]; 

커플 참고로 ... 당신의 mainMOC은 프라이빗 또는 메인 큐 동시성 타입이어야합니다. 핵심 데이터 템플리트를 사용하는 경우, 애플리케이션 위임에있는 곳에서 alloc/init을 initWithConcurrencyType : NSMainQueueConcurrencyType으로 변경하십시오.

그러나 정규 주/부모 관계를 사용하는 것이 좋습니다. 개인용 MOC를 생성하여 영구 저장소에 할당 한 다음 주 MOC를 만들고 그 상위를 해당 개인용 MOC로 설정하십시오. 이제 UI를 차단하지 않고 백그라운드 작업으로 모든 I/O를 처리 할 준비가되었습니다.

여전히 웹에서로드하는 경우 위의 패턴을 사용하십시오. 하위 MOC를 만든 다음 주 MOC에 개체를로드하십시오.

"루트"MOC 호출이 저장 될 때까지 데이터가 디스크에 저장되지 않습니다.

관련 문제