2013-08-30 1 views
1

나는 올바른 방향으로 가고 있다고 생각하지만 여기에서 다시 확인하고 싶습니다. 최근 AFNetworking을 사용하여 데이터베이스에서 큰 XML 파일을 얻었습니다. 그런 다음 구문 분석해야합니다 (나는 그 부분을 모두 알아 냈습니다). 백그라운드 스레드에서 구문 분석을 수행하고 기본 스레드에서 UI를 업데이트하고 싶습니다.AFNetworking : xml 백그라운드에서 구문 분석

self.xmlOperation = 
[AFXMLRequestOperation XMLParserRequestOperationWithRequest: request 
                success: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) { 

                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
                  XMLParser.delegate = self; 
                  [XMLParser setShouldProcessNamespaces:YES]; 
                  [XMLParser parse]; 

                  dispatch_async(dispatch_get_main_queue(), ^{ 
                   [self.searchResultViewController didFinishImport]; 
                   [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; 

                  }); 
                 }); 
                } 
                failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) { 
                 // show error 
                }]; 

[self.xmlOperation start]; 

(가)이 작업을 수행하는 선호/올바른/적절한 방법인가 : 그래서 AFXMLRequestOperation의 성공 블록 안에 다른 dispatch_async 블록을 추가?

+2

네, 맞습니다. – rmaddy

답변

1

꽤 괜찮아 보입니다. 하지만 두 관측 :

  1. 메인 스레드에서 코드의 어떤 개체에 액세스 할 수 있는가가 적극적으로 NSXMLParserDelegate 방법으로 업데이트되고? 그렇지 않다면 괜찮습니다.

    그러나 NSXMLParserDelegate 메서드가 업데이트하는 것과 동일한 개체/컬렉션에 액세스하는 코드가있는 경우 (예 : UI 사용), 해당 공유 리소스를 동기화하는 데주의해야합니다. (자원 동기화에 대한 자세한 내용은 스레딩 프로그래밍 가이드 및/또는 동시성 프로그래밍 가이드의 Eliminating Lock Based Code 섹션의 Synchronization 절을 참조하십시오.를)

    개인적으로, 나는이 별도로 NSXMLParserDelegate 코드를 이동하고자 클래스를 생성하고 개별 요청에 대해 인스턴스화하면 내 요청 및 후속 구문 분석 프로세스가 결코 동기화 문제의 원인이 될 수 없다는 것을 알게됩니다. 여전히 업데이트 모델/저장소 프로세스를 동기화해야하지만 실제로는 주 큐에서 최종 업데이트를 수행하여 업데이트 작업을 수행하고 있습니다.

  2. 첫 번째 UI가 진행되는 동안 UI에서 다른 XML 요청을 실행할 수 있습니까? 그렇지 않다면 괜찮습니다.

    사용자가 첫 번째 진행 중에 두 번째 요청을 시작할 수있는 경우 위임 개체의 동일한 인스턴스를 사용하여 두 가지 동시 처리 요청을 할 수있는 (거의 예상치 못한 경우) 시나리오가 열립니다. 분명히 첫 번째 작업이 완료 될 때까지 (예 : 새로 고침을 요청하는 UI 요소 사용 중지) 연속 요청을 방지하거나 직렬 대기열을 사용하거나 모든 요청에 ​​대해 인스턴스화 할 별도의 클래스로 파서를 옮겨서이 문제를 해결할 수 있습니다. 개인적으로이 구문 분석 요청을 취소 가능하게 만들고 이전 요청을 취소하고 새로운 요청을 발행하는 경향이 있습니다.

코드 샘플을 살펴보면이 두 가지 동시성 관련 문제가 있습니다. 아마도 이들 중 어느 것도 특정 구현에 대한 문제가 아닐 수 있습니다. 그럼에도 불구하고, 코드가 나머지 구현에서 너무 우연하다는 사실 자체가 문제입니다.

+1

Rob에게 문의 해 주셔서 감사합니다. 실제로 당신이 묘사 한 두 가지 관측은 제 경우의 문제는 아닙니다. 또한, 나는 (iOS 책에서 Conway/Hillegass 접근법에 따라 다소 차이가있는) 별도의 수업에서 파싱을하지만이 예제의 명확성을 위해이를 제거했습니다. – Koen

+0

나는 Magical Record로 문제가 발생했습니다. 여기에 나와 있듯이 https://github.com/magicalpanda/MagicalRecord/issues/298, 배경 스레드에서 MR_createEntity를 사용할 수 없습니다. 그리고 MR_createEntity를 사용하여 엔티티를 생성하는 것은 XML을 파싱하는 동안 정확하게 수행 한 작업입니다. 그래서 나는 그 전략을 다시 생각할 필요가있다. – Koen

+0

@Koen Ah, ok. 나는 당신이'NSXMLParserDelegate' 메소드에서 무엇을하고 있었는지 알지 못했습니다.아마도 XML을 일부 컬렉션으로 파싱 한 다음 (중첩 된 배열과 사전이 데이터에 적합한 것인지 여부에 관계없이) 메인 큐에 다시 게시하는 코드에서 구조를 가져 와서 마법 레코드 작업을 수행하게 할 수 있습니다. 행운을 빕니다! – Rob