2011-06-12 5 views
4

나는 다음과 같은 예를 들어 루프에서 레이블을 업데이트 할 :iOS의 UI 요소는 스레드가없는 루프에서 어떻게 업데이트 될 수 있습니까?

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    int i=0; 
    while (1) { 
     i++; 
     [NSThread sleepForTimeInterval:0.05]; // do some computation, 
     [myLabel setText:[NSString stringWithFormat:@"%d", i]]; // show the result! 
     [self.view setNeedsDisplay]; 
    } 

    } 

몇 가지 무거운 계산이 이루어집니다 대신 수면의 가정합니다. 백그라운드에서 계산을 수행하는 오버 헤드를 원하지 않습니다. 이 예로서, .DoEvents 것이이 문제를 처리하기위한 윈도우 상당 보여줍니다 아이폰 OS에서이에 대한 유사한 솔루션 http://www.tek-tips.com/viewthread.cfm?qid=1305106&page=1

있습니까?

[self.view setNeedsDisplay]가 전혀 작동하지 않습니다!

메인 스레드의 제어 된 일정에 따라 iOS의 응용 프로그램 이벤트를 처리하는 방법이 있어야합니다 ... Windows의 .DoEvents와 마찬가지로 모든 단점에도 불구하고 일부 간단한 응용 프로그램에는 매우 유용합니다.

게임 루프와 같지만 UI 구성 요소가있는 것 같습니다.

+0

performSelector : withObject : afterDelay : 을 사용해보세요. http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelector : withObject : afterDelay : inModes : – AmineG

+0

[self.view performSelector : @selector (setNeedsDisplay) withObject : nil afterDelay : 0]; 작동하지 않습니다 ... – brbr

+0

[self performSelectorOnMainThread : @selector (heavyDutyComputation) withObject : nil waitUntilDone : YES]; 작동하지 않습니다 ... – brbr

답변

1

레이블을 사용하여 카운터를 구현한다고 가정합니까? 예를 들어 NSTimer를 사용하여 카운터를 X 밀리 초마다 업데이트하는 메서드를 호출 할 수 있습니다.

+0

이것은 도움이되지 않습니다! 읽어주세요! – brbr

1

UI 구성 요소를 업데이트하려면 iOS에서 NSTimer을 사용하십시오.

NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval: 60.0 target: self 
            selector: @selector(callAfterSomeSecond:) userInfo: nil repeats: YES]; 

는 callAfterSomeSecond 구현 : 아래 : 코드에서

-(void) callAfterSomeSecond:(NSTimer*) timer 
{ 
    static int counter = 0; 

    if(counter == 100) 
    { 
     [timer invalidate]; 
    } 
    [myLabel setText:[NSString stringWithFormat:@"%d", counter ]]; 
    [self.view layoutSubviews]; 
    counter++; 
} 
+0

타이머는 옵션이 아닙니다. 왜냐하면 루프가 종료되지 않고 해당 루프 내에서 사용자 인터페이스를 수정하기를 원하기 때문입니다. 그리고 주 스레드가 차단 된 경우 타이머가 작동한다고 생각하지 않습니다. – brbr

+0

@brbr : 'counter'가 100이 될 때 종료됩니다. 100에서'NSTimer'를 무효로하고있는 것을보십시오. – Jhaliya

0

을, while 루프는 메인 스레드에서 실행하고, UI 업데이트는 루프 동안, 그래서 메인 스레드에서 수행되어야한다 주 스레드는 일종의 '차단됨'(통화 중)이므로 UI ​​업데이트를 수행 할 수 없습니다.

내가 원하는 것은 당신이 원하는 것이 아니라고 생각합니다. 이 문제를 해결하려면 NSOperation 또는 GCD를 사용하여 무거운 컴퓨팅을 다른 스레드에 넣어야합니다. 다음과 같이

3

이 작업을 수행 할 방법은 다음과 같습니다

-(void) incrementCounter:(NSNumber *)i {    
    [myLabel setText:[NSString stringWithFormat:@"%d", [i intValue]]]; // show the result! 
    [self performSelector:@selector(incrementCounter:) withObject:[NSNumber numberWithInt:i.intValue+1] afterDelay:0.05];  
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // start the loop 
    [self incrementCounter:[NSNumber numberWithInt:0]]; 
} 

여기에 기본적인 아이디어는 메인 UI는 모든 UI 이벤트를 플러시 할 수있는 기회를 스레드주고 약간의 지연이 0.05 후 카운터를 증가이다 Windows 세계에서 .DoEvents를 명시 적으로 호출하는 것을 보완합니다.

관련 문제