2012-05-27 2 views
3

인스트루먼트를 사용한 후 코드가 매우 길어서 내 UI가 차단되는 지점을 발견했습니다. 코어 데이터 페치가 많이 발생했습니다 (큰 JSON 패킷을 처리하는 과정의 일부이므로 개체가 복제되지 않도록하면서 관리되는 개체 구축).NSOperationQueues를 사용하는 코어 데이터 및 동시성

내 의도는이 요청을 더 작은 조각으로 나누어 연속적으로 처리하는 것이지만, 그 의미는 내가 그 페치를 펼칠 것임을 의미합니다. 효과는 하나의 길 대신에 작은 크기의 갑작스런 갑작스런 소리가 될 것으로 예상합니다. 딸꾹질.

Apple의 워드 프로세서와 온라인 블로그에서 읽은 모든 내용은 핵심 데이터 및 동시성이 벌집을 파킹하는 것과 비슷하다는 것을 나타냅니다. 그래서, 소심히 나는 그것을 대학에 진학시키기 위해 앉았다. 아래는 내가 생각해내는 것입니다. 나는 내가 작성한 오류가 있음을 지적하면서 누군가를 현명하게 평가할 것입니다.

아래에 게시 된 코드는 작동합니다. 내가 읽은 것은 내가 분명히 그릇된 일을했다는 것을 두려워하게했다. 나는 수류탄에서 핀을 뽑아 내고 예기치 않게 떨어져 나가는 것을 기다리고있는 것처럼 느껴집니다! 당신은 당신이 iOS5를 위해 그 일을해야 NSPrivateQueueConcurrencyType을 사용하고 있기 때문에

NSBlockOperation *downloadAllObjectContainers = [NSBlockOperation blockOperationWithBlock:^{ 
    NSArray *containers = [webServiceAPI findAllObjectContainers]; 
}]; 

[downloadAllObjectContainers setCompletionBlock:^{ 

    NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [backgroundContext setPersistentStoreCoordinator:[_managedObjectContext persistentStoreCoordinator]]; 

    [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification 
                 object:backgroundContext 
                 queue:[NSOperationQueue mainQueue] 
                usingBlock:^(NSNotification *note) { 
                 [_managedObjectContext mergeChangesFromContextDidSaveNotification:note]; 
                }]; 


     Builder *builder = [[Builder alloc] init]; 
     [builder setManagedObjectContext:backgroundContext]; 

     for (ObjectContainer *objCont in containers) { // This is the long running piece, it's roughly O(N^2) yuck! 
      [builder buildCoreDataObjectsFromContainer:objCont]; 
     } 

    NSError *backgroundContextSaveError = nil; 
    if ([backgroundContext hasChanges]) { 
     [backgroundContext save:&backgroundContextSaveError]; 
    } 
}]; 

NSOperationQueue *background = [[NSOperationQueue alloc] init]; 
[background addOperation:downloadAllObjectContainers]; 

답변

6

, 당신은 백그라운드 스레드에서 컨텍스트를 만들고 메인 스레드에서 병합의 모든 문제를 통해 갈 필요가 없습니다.

주 스레드에서 동시성 유형 NSPrivateQueueConcurrencyType을 사용하여 관리 대상 객체 컨텍스트를 만들고 managedObjectContext : performBlock 메서드에 전달 된 블록 내의 관리 객체를 사용하여 모든 작업을 수행하면됩니다.

WWDC2011 세션 303 - iOS의 핵심 데이터의 새로운 기능을 살펴 보시기 바랍니다. 또한 Core Data Release Notes for iOS5을 살펴보십시오.

NSManagedObjectContext 지금 동시 작업에 대한 구조화 된 지원을 제공합니다

다음은 릴리스 노트에서 인용합니다. initWithConcurrencyType :을 사용하여 관리 객체 컨텍스트를 만들면 스레드 (대기열) 연결에 대한 세 가지 옵션이 있습니다.

제한 (NSConfinementConcurrencyType).

이것은 기본값입니다. 컨텍스트가 작성한 스레드가 아닌 다른 스레드에서 컨텍스트를 사용하지 않을 것이라고 약속합니다. (이는 이전 릴리스에서 사용한 스레딩 요구 사항과 동일합니다.)

전용 대기열 (NSPrivateQueueConcurrencyType).

컨텍스트는 개인 큐를 만들고 관리합니다. 컨텍스트가 연결된 스레드 또는 큐를 만들고 관리하는 대신 여기에서 컨텍스트가 큐를 소유하고 모든 세부 정보를 관리합니다 (아래 설명 된 블록 기반 방법을 사용하는 경우).

메인 대기열 (NSMainQueueConcurrencyType).

컨텍스트는 주 큐와 연결되어 있으므로 응용 프로그램의 이벤트 루프에 연결되지만 그렇지 않으면 개인 큐 기반 컨텍스트와 유사합니다. 주 스레드에서만 사용해야하는 컨트롤러 및 UI 개체에 연결된 컨텍스트에는이 큐 유형을 사용합니다.

+0

iOS 5에서만 사용하고 있습니다. "핵심 데이터와 병행 성"도움말에서는이를 호출하지 않으며 iOS 5.0 API Diffs에서 제안한 내용을 찾을 수 없습니다. NSManagedObjectContext에 대한 설명서는 해당 상수에 대해 약간 간결합니다. 참조하는 문서의 방향을 알려주시겠습니까? – edelaney05

+0

예, 귀하의 의견을 언급하기 위해 원래 게시물을 편집했습니다. – svena

0

동시성

동시성 동시에 둘 이상의 큐에 데이터와 함께 작동 할 수있는 능력이다. 핵심 데이터와 동시성을 사용하기로 선택한 경우 응용 프로그램 환경도 고려해야합니다. 대부분 AppKit과 UIKit은 스레드로부터 안전하지 않습니다. 특히 OS X에서는 코코아 바인딩과 컨트롤러가 스레드 세이프가 아닙니다. Core Data, Multithreading, and the Main Thread