2010-08-21 5 views
0

작은 문제로 작업에 중단되었습니다. 응용 프로그램에 wifi 연결을 사용하면 거의 즉시 수행되는 몇 가지 웹 쿼리가 포함되어 있지만 3G 또는 EDGE 연결의 경우에는 몇 초가 걸릴 수 있습니다. 이 기간 동안 사용자에게 검색어가 진행 중임을 나타내려고합니다. 라벨에 메시지를 표시합니다. 실제로는 어떻게됩니까웹 쿼리가 진행 중일 때 경고?

-(void)query{ 
    alertLabel.text = @"in progress…"; 

    // the query follows... 
    NSString *queryURLstring = [NSString stringWithFormat:@"http://xyz.xyz"]; 
    NSURL *queryURL = [[NSURL alloc] initWithString:queryURLstring]; 
    NSString *receivedData = [[NSString alloc] initWithContentsOfURL:queryURL]; 
    //query done 

    alertLabel.text = @""; 
} 

쿼리가 실행되고있을 때, 사용자가 실제로 아무것도 할 수 없다는 것입니다 :

코드는 다음과 같이 보입니다. 요청 된 데이터가 수신되면 "진행 중 ..."텍스트가 잠시 동안 나타나고 즉시 사라집니다. 이것이 어떻게 작동하는지 이해할 수 없으므로 이해할 수 없습니다. 텍스트는 쿼리가 실행되기 전에 레이블에 표시되어야하며 끝나면 지워야합니다. 누구도 그런 문제에 직면 했습니까? 해결책을 추천 해 주시겠습니까? 모든 종류의 제안에 감사드립니다. Miv

+0

내 편집 내용보기 - 코드처럼 보이게 코드를 구성했습니다. 각 코드 행은 4 칸 이상으로 시작해야합니다. –

답변

0

문제에 대한 해결책은 거의 없습니다.
@Eiko는 문제와 그 이유를 매우 잘 설명했습니다. 하여 alertLabel.text = @"in progress…";

[self performSelectorInBackground:@selector(query) withObject:nil]; 

그리고 대체 :

그냥 같은 백그라운드 스레드에서 query 방법을 실행

다음 (코드 변경의 최소한의 금액) 하나 개의 가능한 솔루션입니다

[alertLabel performSelectorOnMainThread:@selector(setText:) withObject:@"in progress…" waitUntilDone:NO]; 

[ alertLabel.text = @""; 대해 동일]

당신이한다면 그것은 더 나은 것 : - (void)showLoadingWithText:(id)loadingText;- (void)hideLoading; :

  • 2 가지 방법을 추가합니다.
  • 레이블에서 직접 선택기를 수행하는 대신 주 스레드에서이 메소드를 호출하십시오.
  • [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; (헤더에로드 표시기가 표시됨) 또는 사용자 정의 UIActivityIndicatorView (여기서는 alertLabel 근처에 위치해야 함)과 같은 몇 가지 추가 활동 표시기를 추가하십시오.
+0

Michael, 감사합니다. 제안 된 솔루션은 좋지만 다음과 같이 구현해야합니다. 1. 배경 스레드에 경고 레이블 표시 2. 메인 스레드에서 다운로드 시작 3. 완료 (성공 또는 오류)되면 레이블을 제거합니다 - 백그라운드 스레드에서 즉 : - (BOOL) 쿼리 (myDataT *) 데이터 { [alertLabel performSelectorInBackground : @selector (의 setText : withObject : @ "진행 중 ..."]; // 쿼리 ... // 쿼리 수행 // 수신 데이터 처리 ... 데이터 -> 결과 = ...; // ... [alertLabel performSelectorInBackground : @selector (setText :) withObject : @ ""]]; return retVal; } – cactusdev

+0

@cactusdev 이것은 정확히 수행해야 할 작업의 반대입니다. UI와의 모든 상호 작용 (예 : 레이블에 대한 setText)은 주 스레드에서 수행되어야하며 모든 중량/긴 처리 (예 : 동기 연결)는 백그라운드에서 수행되어야합니다. –

+0

Michael, 맞습니다. 물론 실제로는 반대 (즉, 정상적인) 작업을 구현하는 방법을 모르겠습니다. 또한 내가 에이코의 대답 (주 스레드가 쿼리에서 데이터를 기다려야 할 것이라고)에 대한 내 응답에서 언급 한 문제는 다른 문제는 bkgnd에서 쿼리를 실행하려고하면 응용 프로그램이 충돌하는 것입니다.이 오류는 알 수없는 출처가 아닙니다 하지만 확실히 코드에 내 잘못이 - 단지 무엇이 잘못되었는지 알아낼 필요가 ... – cactusdev

0

데이터를 비동기 적으로로드해야합니다.

  1. 는 마무리 (성공 또는 오류)시 비동기
  2. 다운로드 경고 라벨
  3. 시작 라벨을 제거를 표시합니다.

예상보다 오래 걸리고 주 스레드를 차단하면 전체 응용 프로그램이 자동으로 종료 될 수 있습니다.이 문제가 발생하지 않도록 확실히하십시오!

화면의 업데이트 내용. 업데이트는 현재 실행 루프 반복의 끝에서만 발생하므로 완전히 예상되는 동작입니다. (솔직히 말해서, 나는 테스트가 전혀 보이지 않는 것에 놀랐다).

+0

경고보기 대신/추가로 UIProgressView를 사용할 수도 있습니다. http://developer.apple.com/iphone/library/documentation/uikit/reference/UIProgressView_Class/Reference/Reference.html – Kalle

+0

사실 그는 실제로 방해가되지 않는 라벨을 사용합니다. 그러나 진도보기는 좋은 제안 또는 활동보기입니다. – Eiko

+0

Eiko, 답변 해 주셔서 감사합니다. 그러나 나는 당신이 제안한 것보다 조금 다른 방식으로 해결했다. 내 새로운 문제 : 쿼리 메서드는 개체에서 결과를 매개 변수로 반환합니다. 이 응용 프로그램은 단일 스레드 방식으로 작동하도록 구성되었습니다 ... 쿼리가 백그라운드로 실행되면 주 스레드는 쿼리를 완료 할 때만 사용할 수있는 데이터를 놓칩니다. 메인 쓰레드를 어떻게 대기시킬 수 있습니까? 반복 타이머가 0.1 초로 설정되어 데이터가 이미 반환되었는지 확인합니다 ...? 사실 나는 다른 생각은 없지만 그것을 해결하는 더 좋은 방법이 있어야합니다. – cactusdev

관련 문제