2013-10-14 2 views
9

로컬 노드 서버에서 일부 데이터를 가져 오려고합니다. 서버가 get 요청을 받고 그것을 로깅하지만, 어떤 이유로 iOS 어플리케이션이 완성 핸들러에있는 코드를 실행하지 않습니다.NSURLSessionDataTask가 완료 핸들러 블록을 실행하지 않습니다.

- (IBAction) buttonPressed{ 
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:3000/"]; 
NSURLSessionDataTask *dataTask = 
[self.session dataTaskWithURL:url 
      completionHandler:^(NSData *data, 
           NSURLResponse *response, 
           NSError *error){ 
       nameLabel.text = @"yay!"; 
       /* 
       if (!error){ 
        nameLabel.text = @"noerr"; 
        NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response; 
        if (httpResp.statusCode == 200){ 
         NSError *jsonErr; 

         NSDictionary *usersJSON = 
         [NSJSONSerialization JSONObjectWithData:data 
                 options:NSJSONReadingAllowFragments 
                 error:&jsonErr]; 

         if (!jsonErr){ 
         // nameLabel.text = usersJSON[@"username"]; 
          nameLabel.text = @"nojerr"; 

         } 
         else{ 
          nameLabel.text = @"jsonErr"; 
         } 
        } 
       } 
       else{ 
        nameLabel.text = @"Err"; 
       } 
       */ 
      }]; 
[dataTask resume]; 

} 프로그램을 실행하면

의 nameLabel는 변경되지 않습니다에 "야호"여기에 코드입니다. 그러나 NSURLSessionDataTask 줄 앞에 nameLabel 변경하려고하면 변경됩니다.

+0

도움이 되었으면 아래에서 답변을 선택하십시오. 답과 관련된 질문이 있으시면 언제든지 말씀해주십시오. – wigging

답변

14

NSURLSessionDataTask은 백그라운드 스레드에서 실행됩니다. 레이블, 단추, 표보기 등과 같은 사용자 인터페이스의 내용을 업데이트하려면 주 스레드에서 변경해야합니다. 당신이 completionHandler 블록에서 레이블 텍스트를 업데이트 할 경우에 당신은과 같이 메인 스레드에서 레이블을 업데이트해야합니다 :

static NSURLSession* sharedSessionMainQueue = nil; 
if(!sharedSessionMainQueue){ 
    sharedSessionMainQueue = [NSURLSession sessionWithConfiguration:nil delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; 
} 

NSURLSessionDataTask *dataTask = 
[sharedSessionMainQueue dataTaskWithURL:url completionHandler:^(NSData *data, 
           NSURLResponse *response, 
           NSError *error){ 
    //now will be on main thread 
}]; 
[dataTask resume]; 

이 당신에게 원래의 동작을 제공합니다

dispatch_sync(dispatch_get_main_queue(), ^{ 
    nameLabel.text = @"yay!"; 
}); 
12

이 마술을 시도 NSURLConnection을 주 스레드의 완료 핸들러와 함께 사용하면 UI를 안전하게 업데이트 할 수 있습니다. 그러나 다운로드를 구문 분석하거나 무거운 처리를 수행하려는 경우 작업 대기열의 백그라운드 스레드에서 완료 핸들러를 사용하고 마지막 단계로 기본 스레드에 dispatch_sync를 사용하면 도움이 될 수 있습니다.

+2

+1 - 백그라운드 스레드에서 추가 작업을 실행하고 모든 스레드가 주 스레드에서 실행되는 것으로 가정 할 수 있으므로 * 더 나은 방법입니다. –

+0

흠, Jonathon이 완료 블록에서이 방법을 사용하는 경우 주 스레드에서 (유일한 경우에만 가능)됩니다. – Fattie

+0

Joe는 필요한 경우 주 스레드 완성 블록에서 백그라운드 스레드를 작성한다는 의미입니다. – malhal

관련 문제