0

에서 절약을 수행하기 위해 어떻게 NSFetchedResultsController에 매여 테이블보기가 있고, 해당 managedObjectContext는 self.myDatabase.managedObjectContext입니다 :UIManagedDocument : 배경

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
                    managedObjectContext:self.myDatabase.managedObjectContext 
                     sectionNameKeyPath:nil 
                       cacheName:nil]; 

이제 사용자가 내가 실행 페이지를 새로 고침 할 때마다 다음 코드.

dispatch_queue_t fetchQ = dispatch_queue_create("fetcher", NULL); 
dispatch_async(fetchQ, ^{   
    NSArray *data = [MyAPI myData]; 

    [document.managedObjectContext performBlock:^{ 
     for (NSDictionary *info in data) { 
      [MyEntity createOrUpdateGivenInfo:info andManagedObjectContext:self.myDatabase.managedObjectContext]; 
     } 
    }]; 
}); 
dispatch_release(fetchQ); 

이 잘 작동 : 본질적으로, 나는 MOC-스레드 안전에 새 데이터를 데이터를로드 한 후 업데이트/저장하는 새로운 스레드를 만들 내 업데이트를하고 테이블 뷰가 제대로 모든 것을 표시하고 . 문제는 UI가 응답하지 않는다는 것입니다. 아마도 메인 스레드에서 저장/업데이트를 수행했기 때문일 수 있습니다. UI를 지금 반응하는 동안, 나는 테이블보기와 문제의 부하를 얻을

NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] init WithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [backgroundContext setParentContext:self.myDatabase.managedObjectContext]; 

    [backgroundContext performBlock:^{  
     NSArray *data = [MyAPI myData]; 

     for (NSDictionary *info in data) { 
      [MyEntity createOrUpdateGivenInfo:info andManagedObjectContext:backgroundContext]; 
     } 

     [backgroundContext save:nil]; 

     [document.managedObjectContext performBlock:^{ 
     [document updateChangeCount:UIDocumentChangeDone]; 
     }]; 
    }]; 

그러나 : 대신 기존 항목 테이블 표시를 업데이트 그래서 나는이 수정으로 백그라운드 스레드에서이를 수행으로 보았다 여분의 항목 (존재하지 않아야하는 복제본). 두 컨텍스트가 동기화/병합되지 않기 때문에 생각할 수 있지만 이전의 게시물을 읽음으로써 backgroundContext에서 save를 호출 한 다음 주 MOC에서 updateChangeCount를 호출해야한다고 생각하게되었습니다. 앱을 다시 시작하면 다시 새로 고칠 때까지 모든 것이 정상적으로 작동합니다.

아무도 도움이되지 않습니다. 나는 말 그대로 머리카락을 꺼내기 시작했습니다.

당신이이 수수께끼를 풀 수 있다면 나는 맥주를 줄 것이다.

+0

배경 컨텍스트 처리에 대한 일반적인 생각이 맞습니다. createOrUpdateGivenInfo에 대한 코드를 게시하십시오. andManagedObjectContext : 오 그래 ... 또한 NSFetchRequest 및 NSFetchedResultsController에 대한 설정 - 병합을 올바르게 가져 오거나 처리하지 못하는 것처럼 들릴 수 있습니다. –

답변

2

UIManagedDocument은 루트 컨텍스트가 NSPrivateQueueConcurrencyType이고 하위 컨텍스트가 NSMainQueueConcurrencyType 인 두 개의 컨텍스트를 만듭니다.

NSFetchedResultsController을 연결하십시오. 이는 메인 스레드의 컨텍스트이므로 수행 한 것입니다.

읽기/쓰기는 백그라운드 스레드에서 자동으로 이 발생합니다.UIManagedDocument이 처리합니다. 당신은 그것에 대해 걱정할 필요가 없습니다.

너 자신을 무겁게해야 할 경우 NSMainQueueConcurrencyType이라는 또 다른 관리 대상 개체를 만들고 그 부모 인 document.managedObjectContext을 부모로 만듭니다.

코드를 읽었는데 이것이 사용자가하는 것처럼 보이며 작동합니다. 그게 내 애플 리케이션에서 정확히 어떻게 그랬어. 그러나 나는 프레임 워크 버그가 있다고 의심하여 ​​NSFetchedResultsController과 중복 된 항목을보고하는 몇몇 다른 사람들을 보았습니다.

프로젝트를 공유하고 싶다면 좀 살펴 보겠습니다.