2012-08-05 4 views
1

내 앱이 dispatch_async를 사용하고 구문 분석하는 JSON 결과를 가져 오는 Google API 호출을 만들도록했습니다. 진행률보기를 구현하여 구문 분석 한 JSON 응답의 결과 수에 따라 업데이트를 진행합니다.dispatch_async 내의 UIProgressView 업데이트

그래서 내 dispatch_async 구글 API 호출은 다음과 같습니다

dispatch_async(myQueue, ^{ 

    NSData* data1 = [NSData dataWithContentsOfURL:googleURL]; 
    [self performSelectorOnMainThread:@selector(fetchResultsForGoogle:) withObject:data1 waitUntilDone:YES]; 
}); 

fetchResultsForGoogle: withObject: 방법은 결과를 구문 분석, 그리고 처리 결과의 수와 화면의 진행보기를 표시합니다.

float percentage = (float)counter/(float)totalItems; 
     self.progressView.progress = percentage; 
     NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @" complete"]; 
     self.progressViewLabel.text = percentText; 

을하지만 생각 dispatch_async 다른 스레드에서 수행 할 때, 당신은 dispatch_async(dispatch_get_main_queue()를 사용하지 않고 메인 스레드에서보기를 업데이트 할 수 없습니다 이해 : 그래서 fetchResultsForGoogle... 방법에서, 내가 갖고 싶어. 이 문제를 해결하기 위해이 두 가지 방법 (아래 참조)을 시도했지만 이러한 방법 중 하나가 작동하지 않습니다 (progressViewprogressViewLabel 전혀 업데이트하지 않음).

계획 A :

dispatch_async(myQueue, ^{ 

     NSData* data1 = [NSData dataWithContentsOfURL:googleURL]; 
     [self performSelectorOnMainThread:@selector(fetchResultsForGoogle:) withObject:data1 waitUntilDone:YES]; 

dispatch_async(dispatch_get_main_queue(), ^{ 

      float percentage = (float)counter/(float)totalItems; 
      self.progressView.progress = percentage; 
      NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @"complete"]; 
      NSLog(@"Percentage: %@", percentText); 
      self.progressViewLabel.text = percentText; 
     }); 

    }); 

플랜 B :

dispatch_async(myQueue, ^{ 

      NSData* data1 = [NSData dataWithContentsOfURL:googleURL]; 
      [self performSelectorOnMainThread:@selector(fetchResultsForGoogle:) withObject:data1 waitUntilDone:YES]; 

     }); 

그리고이 fetchResultsForGoogle... 메소드 내 :

dispatch_async(dispatch_get_main_queue(), ^{ 

       float percentage = (float)counter/(float)totalItems; 
       self.progressView.progress = percentage; 
       NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @"complete"]; 
       NSLog(@"Percentage: %@", percentText); 
       self.progressViewLabel.text = percentText; 
      }); 

그래서 올바른 방법에 관한 아이디어 나 팁은 구현이 매우이다 매우 감사!

IT는 내가 그것을 고정 편집-해결했다. dispatch_async 블록에서는 performSelectorOnMainThread으로 전달했습니다. 따라서 진행률보기를 performSelectorOnMainThread으로 업데이트하려고 시도하면 dispatch_async이 완료 될 때까지 UI가 업데이트되지 않습니다.

그래서 dispatch_async 블록 내에서 performSelectorInBackgroundThread으로 변경했으며 이제는 performSelectorOnMainThread이 UI를 업데이트해야합니다.

나는 이것에 대해 새로운 것이지만 나는 여전히 새로운 것을 배우고있어서 기쁩니다.

+0

에 레이블 및 progressView를 업데이트 할 수 있습니다? – Mazyod

+3

performSelectorOnMainThread를 호출하고 메인 큐에서 dispatch_async를 호출하는 이유는 무엇입니까? 또한이 질문은 너무 혼란 스럽습니다. 이러한 발췌문보다는 문제가있는 전체 메서드를 게시하는 것이 더 합리적입니다. –

+0

@JodyHagins가 performSelectorOnMainThread에 대한 여러분의 의견을 보았습니다. 미안 해요, 제 질문이 혼란 스러웠습니다. dispatch_async에서 performSelectorInBackgroundThread로 변경하고 이제는 작동합니다. – BlueChips23

답변

0

당신이하는 것처럼 당신은 주 스레드에서 일을 업데이트 할 수 없습니다. 다음과 같이 주 스레드에서 선택자를 수행해야합니다.

비율이 어느 부분에서 변경되는지는 정확히 모르지만 그 아래에 선을 추가하십시오. 문`; 그리고 당신은 또한 ("%의 @ 비율"@)가`NSLog에 의해 생성 된 로그를 추가 할 수 메인 스레드

[self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSNumber numberWithFloat:percentage] waitUntilDone:NO]; 


-(void) updateProgress:(NSNumber *) num { 
     float percentage = [num floatValue]; 
     self.progressView.progress = percentage; 
     NSString *percentText = [NSString stringWithFormat:@"%f %% %@", percentage, @" complete"]; 
     self.progressViewLabel.text = percentText; 
}