2010-01-03 6 views
2

인터넷에서 ZIP 파일을 다운로드 할 수 있습니다. 게시물 처리는 connectionDidFinishLoading에서 수행되며 UIView 요소가 업데이트되지 않는 것을 제외하고는 정상적으로 작동합니다. 예를 들어, statusUpdate.text = @ "Uncompressing file"을 설정했지만 connectionDidFinishLoading이 완료 될 때까지 변경 사항이 표시되지 않습니다. 같이,이 메소드가 종료 할 때까지 UIProgressView 및 UIActivityIndicatorView 객체는 갱신되지 않습니다.connectionDidFinishLoading - 강제로 UIView를 업데이트 하시겠습니까?

이 방법 내에서 UIView를 강제로 업데이트 할 수있는 방법이 있습니까? 나는 [self.view setNeedsDisplay]를 설정하려고했지만 작동하지 않았다. 그것은 주 스레드에서 실행중인 것으로 보입니다. 다른 모든 명령은 잘 작동합니다. 유일한 문제는 UI 업데이트입니다.

감사합니다.

업데이트 : 여기에 UIView를 업데이트하지 않는 코드입니다 :

-(void)viewWillAppear:(BOOL)animated { 
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(processUpdate:) userInfo:nil repeats:YES]; 
    downloadComplete = NO; 
    statusText.text = @""; 

} 

-(void)processUpdate:(NSTimer *)theTimer { 
    if (! downloadComplete) { 
     return; 
    } 

    [timer invalidate]; 
    statusText.text = @"Processing update file."; 
    progress.progress = 0.0; 
     totalFiles = [newFiles count]; 
    for (id fileName in newFiles) { 
     count++; 
      progress.progress = (float)count/(float)totalFiles; 
     // ... process code goes here ... 
     } 
} 

다음 processUpdate의 끝에서, 나는이 downloadComplete = 설정 YES. 이것은 &을 오류없이 실행하며 processUpdate가 완료 될 때까지 UIVIEW의 업데이트를 제외하고 의도 한대로 작동합니다. 그런 다음 모든 내용이 한 번에 업데이트됩니다.

지금까지 도와 주셔서 감사합니다.

답변

0

for() 루프에서 UI가 업데이트되지 않는다는 문제가 발생했습니다. 간단한 해결책은 the answer in this thread을 참조하십시오!

0

DidFinishLoading 중에 응용 프로그램 실행 루프에서 아무 것도 일어나지 않습니다. 컨트롤을 실행 루프로 다시 전달하여 UI 업데이트를 조정할 수 있어야합니다.

데이터 전송을 완료로 플래그 지정하고 업데이트 할보기 만 허용합니다. 다운로드 한 데이터의 무거운 처리를 자체 스레드로 연기하십시오.

응용 프로그램은 나중에 실행 루프에서 내용을 새로 고칠 수 있도록보기를 다시 호출합니다. 적절한대로 사용자 정의보기에서 drawRect를 구현하십시오.

0

주 스레드에서 connectionDidFinishLoading을 수신하는 경우 운이 없게됩니다. 이 메서드에서 반환하지 않는 한 UI에서 아무 것도 새로 고쳐지지 않습니다. 비 주에서 UI를 업데이트하지 않도록주의

UIProgressView *prog = ... <your progress view reference> ... 
[prog performSelectorOnMainThread:@selector(setProgress:) 
         withObject:[NSNumber numberWithFloat:0.5f] 
        waitUntilDone:NO]; 

: 당신이 별도의 스레드에서 연결을 실행하는 경우

한편

, 당신은 안전하게 다음 코드를 사용하여 UI를 업데이트 할 수 있습니다 스레드 - 항상 performSelectorOnMainThread 메서드를 사용하십시오!

1

Niels가 말한 것처럼보기 업데이트를보고 싶다면 실행 루프로 제어를 되돌려 야합니다. 그러나 정말로 필요하지 않으면 새 스레드를 분리하지 마십시오. 이 방법을 권장합니다 :

- (void)connectionDidFinishLoading:(NSConnection *)connection { 
    statusUpdate.text = @"Uncompressing file"; 
    [self performSelector:@selector(doUncompress) withObject:nil afterDelay:0]; 
} 

- (void)doUncompress { 
    // Do work in 100 ms chunks 
    BOOL isFinished = NO; 
    NSDate *breakTime = [NSDate dateWithTimeIntervalSinceNow:100]; 
    while (!isFinished && [breakTime timeIntervalSinceNow] > 0) { 
     // do some work 
    } 
    if (! isFinished) { 
     statusUpdate.text = // here you could update with % complete 
     // better yet, update a progress bar 
     [self performSelector:@selector(doUncompress) withObject:nil afterDelay:0]; 
    } else { 
     statusUpdate.text = @"Done!"; 
     // clean up 
    } 
} 

기본적인 아이디어는 작은 덩어리로 작업한다는 것입니다. 실행 루프가 주기적으로 실행되도록 메소드에서 복귀합니다. performSelector :를 호출하면 컨트롤이 결국 객체로 돌아옵니다.

이렇게하는 위험은 사용자가 예상치 못한 버튼을 누르거나 UI와 상호 작용할 수 있다는 점입니다. UIApplication의 beginIgnoringInteractionEvents에 전화를 걸어서 일하는 동안 입력을 무시하는 것이 도움이 될 수 있습니다. 정말 좋을 때가 아니라면 doUncompress 메소드에서 확인하는 플래그를 설정하는 취소 버튼을 제공하십시오.

실행 루프를 직접 실행 해보고 [[NSRunLoop currentRunLoop] runUntilDate:...]을 자주 호출 할 수도 있지만 직접 시도한 적이 없습니다.

+0

감사합니다. 설명 된대로 (복사 및 붙여 넣기)이 구현 된 있지만 while() 루프에서 중단되고 절대로 입력합니다. 나는 이것을 시뮬레이터에서 돌리고있다. 매달려있는 이유는 무엇입니까? – waltcrit

+0

루프 조건이 잘못되었습니다 ('<0' 대신'> 0'이어야합니다). 나는 내 대답을 고쳤다. 어쩌면 그것은 당신의 코드에 문제가있는 것입니까? 그렇지 않으면 말할 충분한 정보가 없습니다. – benzado

+0

이 작품, 고마워요! – waltcrit

0

정확하게 타이머로 무엇을하고 있는지, ConnectionDidFinish :가있는 새 스레드에 처리 코드를 보내면됩니다. 타이머는 메인 스레드에서 실행되기 때문에 UI를 업데이트 할 수 있습니다.

관련 문제