我有一个已关联的UILabel
@property (strong, nonatomic) IBOutlet UILabel *label;
一个动作,由按钮
触发- (IBAction)buttonPressed:(UIButton *)sender;
当按下按钮时,我想更新标签以显示最长3分钟的运行时间,所以我
- (IBAction)buttonPressed:(UIButton *)sender {
for (int i =0; i < 180; ++i) {
[label setText:[NSString stringWithFormat:@"%d", i]];
sleep(1);
}
}
确认,方法被调用,计时器正在滴答..但标签文本不会改变。我做错了什么?
答案 0 :(得分:2)
sleep()
不允许UI线程自行更新。
以下是使用GCD的示例,它与原始代码非常匹配。注意:有更好的方法(请参阅:dispatch_after()
)。
- (IBAction)buttonPressed:(UIButton *)sender {
[label setText:[NSString stringWithFormat:@"%d", 0]];
dispatch_queue_t queue = dispatch_queue_create("com.test.timmer.queue", 0);
dispatch_async(queue, ^{
for (int i = 1; i < 180; ++i) {
sleep(1);
dispatch_async(dispatch_get_main_queue(), ^{
[label setText:[NSString stringWithFormat:@"%d", i]];
});
});
}
答案 1 :(得分:2)
你的sleep()在主线程中,你的视图无法刷新,你可以使用NSTimer来做它。
- (void)update
{
[label setText:[NSString stringWithFormat:@"%d", i]];
i++;
if(i>=100)
{
[timer invalidate];
}
}
- (IBAction)buttonPressed:(UIButton *)sender
{
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES];
[timer fire];
}
答案 2 :(得分:1)
您必须退回到runloop以允许控件刷新。您应该使用每秒钟左右触发的NSTimer,而不是紧密循环。
虽然不是真的推荐,但如果您在setText之后立即调用它,则以下内容也可能有效:
[[NSRunLoop currentRunLoop] acceptInputForMode:NSDefaultRunLoopMode beforeDate:nil];
答案 3 :(得分:0)
所有与UI相关的事情都在主线程中完成。强制运行时在主线程上休眠将直接冻结您的UI。做了180次,你有一个沮丧的最终用户。