我想从循环中更新标签,例如:
- (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 :(得分: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。
答案 1 :(得分:1)
我假设你想用标签实现一个计数器?例如,您可以使用NSTimer来调用每隔X毫秒更新计数器的方法。
答案 2 :(得分:1)
如果要更新UI组件,请在NSTimer
中使用iOS
。
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++;
}
答案 3 :(得分:0)
在你的代码中,while循环在主线程中运行,UI更新也应该在主线程中完成,所以当循环运行时,主线程有点'阻塞'(忙),所以UI无法执行更新。
我想我想说的不是你想要的。要解决它,你必须使用NSOperation或GCD将重计算放在另一个线程中。
答案 4 :(得分:0)
最好的方法是在不同的线程上进行计算,但是如果不可行,可以将影响UI的代码包装在CATransaction中。在我的测试中,这将立即更新UI,而无需等到下一个运行循环。
while (1) {
[CATransaction begin];
//Your UI code here
[CATransaction commit];
}