2011-06-12 66 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]; 
    } 

    } 

假設,而不是睡眠一些繁重的計算完成。 我不想在後臺執行計算的開銷。 當於Windows中處理這個問題將是.DoEvents,如下例所示: http://www.tek-tips.com/viewthread.cfm?qid=1305106&page=1

是否有iOS的這種類似的解決方案?

[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 2011-06-12 18:25:53

+0

[self.view performSelector:@selector(setNeedsDisplay)withObject:nil afterDelay:0];不工作... – brbr 2011-06-12 18:45:03

+0

[self performSelectorOnMainThread:@selector(heavyDutyComputation)withObject:nil waitUntilDone:YES];不起作用... – brbr 2011-06-13 06:46:07

回答

1

我假設你想實現使用標籤的櫃檯?例如,您可以使用NSTimer調用每X毫秒更新計數器的方法。

+0

這沒有幫助!請閱讀! – brbr 2011-06-12 18:42:10

1

使用NSTimeriOS如果你想更新UI組件。

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 2011-06-12 18:51:11

+0

@brbr:當'counter'變爲100時它將退出。看到我在100處使'NSTimer'無效。 – Jhaliya 2011-06-12 18:52:46

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]]; 
} 

這裏的基本思路是增加計數器稍有延遲0.05後得到主UI線程有機會刷新所有UI事件,彌補了在Windows世界中明確調用.DoEvents。