2012-05-28 5 views
1

다음 코드는 서버 (실제로는 내 컴퓨터)에 연결하고, 일부 데이터를 다운로드하고, 직렬화 해제하고 전역 변수에 할당하는 코드입니다.변수가 비동기 적으로 호출되는 블록에 설정되지 않습니다.

UINavigationController *navController = (UINavigationController *)self.window.rootViewController; 
MasterViewController *masterController = [navController.viewControllers objectAtIndex:0]; // masterController is a UITableViewController subclass 
NSMutableArray *surveys = [[NSMutableArray alloc] init]; 
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8000/testapp/survey-data"]; 
NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *rep, NSData *d, NSError *err) { 
    if(d) { 
     NSMutableArray *allSurveys = [NSJSONSerialization JSONObjectWithData:d options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil]; 
     for(NSMutableArray *item in allSurveys) { 
      NSString *title = [item objectAtIndex:[item count] - 1]; 
      [item removeLastObject]; 
      Survey *survey = [[Survey alloc] initWithArray:item title:title]; 
      [surveys addObject:survey]; 
     } 
     masterController.surveys = surveys;
 

     NSLog(@"%@", [masterController.surveys description]); 
    } 
}]; 

불행히도, 작동하지 않습니다. NSLog() (처리기 블록 내부)은 예상대로 모든 데이터를 인쇄합니다. 분명히 연결이 작동 중입니다. 그러나 뷰는 업데이트되지 않으며 행은 모두 비어 있습니다. 다운로드가 완료된 후 블록이 호출되기 때문에 이런 일이 발생합니까? 어떻게 이것을 피할 수 있습니까?

블록에 변수를 설정하여 발생했을 수도 있습니다. 하지만 Apple의 설명서를 살펴 보았습니다. 문제가되지 않아야합니다. masterViewController에 대한 참조를 통해 배열을 설정하고 있기 때문입니다. 내가 잘못?

나는 이것을 잘 작성한 [NSURLConnection sendSynchronousRequest:returningResponse:error:을 사용하여 다시 써 보았습니다. 그러나 동기 요청은 네트워크가 느리거나 다운되면 끔찍한 생각 일 수 있으므로이 작업을 비동기 적으로 수행해야합니다.

+2

은 masterController 인 tableView입니까? 그렇다면이 작업이 완료된 후에 reloadData를 호출해야합니다. – lnafziger

+0

내가 나쁜 코드를 작성하고 있는지 여부는 잘 모르겠지만 sendAsynchronousRequest를 사용하는 것은 좋지 않습니다. 대리인과 NSURLRequest를 사용하여 비동기 다운로드를 수행하는 방법에 대한 공식 문서를 확인하십시오. – nhahtdh

+0

여기에도 다른 동기화 문제가 있습니다. 새 데이터를 작성하는 도중에 설문 조사가 처리되기 시작하면 어떻게됩니까? – lnafziger

답변

1

당신이 데이터를 얻기 전에보기로드, 당신은 당신의 테이블보기에 reloadData를 호출 할 필요가 있기 때문에 데이터가 도착하면

다른 문제를 방지하려면 UIKit 클래스는 스레드로부터 안전하지 않으므로 주 스레드에서이 작업을 수행해야합니다.

1

AsynchronousRequest UI를 업데이트, 일 주 스레드를 사용하지 않는 UI 업데이트 사용하기 때문에이 :

dispatch_async(dispatch_get_main_queue(), ^{ 
    //UI update here  
}); 
관련 문제