在iOS中设置标签文字时遇到问题

我有一个连接的UILabel

 @property (strong, nonatomic) IBOutlet UILabel *label; 

还有一个Action,是由button触发的

 - (IBAction)buttonPressed:(UIButton *)sender; 

当按下button,我想更新标签显示运行秒数达3分钟,所以我

 - (IBAction)buttonPressed:(UIButton *)sender { for (int i =0; i < 180; ++i) { [label setText:[NSString stringWithFormat:@"%d", i]]; sleep(1); } } 

确认,方法被调用,计时器正在滴答滴答。标签文本却没有改变。 请问我做错了什么?

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

你的睡眠()是在主线程中,你的视图不能刷新,你可以使用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]; } 

您必须退回到您的runloop以允许控制刷新。 你可能应该使用一个NSTimer,每隔一秒钟就会发生,而不是一个紧密的循环。

虽然不是真的推荐,但是如果你在setText之后调用它,下面的方法也可以工作:

 [[NSRunLoop currentRunLoop] acceptInputForMode:NSDefaultRunLoopMode beforeDate:nil]; 

所有与UI相关的事情都在主线程中完成。 强制你的运行时间睡在主线程将从字面上冻结你的用户界面。 做180次,你有一个沮丧的最终用户。