iOS中的UI元素如何从没有线程的循环中更新?
问题描述:
我想更新从一个循环的标签,例如像这样: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组件。
答
使用NSTimer
在iOS
如果你想更新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++;
}
答
在你的代码
,while循环在主线程中运行,而UI更新也应该在主线程中完成,因此而循环正在运行,主线程是'阻塞'(繁忙),所以UI更新无法执行。
我想我想说的是不是你想要的。为了解决这个问题,你必须将重载计算放在另一个线程中,例如使用NSOperation或GCD。
答
你会做到这一点的方法如下:
-(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。
尝试使用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
[self.view performSelector:@selector(setNeedsDisplay)withObject:nil afterDelay:0];不工作... – brbr 2011-06-12 18:45:03
[self performSelectorOnMainThread:@selector(heavyDutyComputation)withObject:nil waitUntilDone:YES];不起作用... – brbr 2011-06-13 06:46:07