0

我有一个连接UILabel

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

还有一个Action,由按钮触发

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

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

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

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

4

4 回答 4

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]];
        });
    });
}
于 2012-07-26T03:10:14.183 回答
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];
}
于 2012-07-26T03:27:53.790 回答
1

您必须退出回您的运行循环以允许控件刷新。您可能应该使用每秒触发一次的 NSTimer 而不是紧密循环。

虽然不是很推荐,但如果您在 setText 之后立即调用它,以下可能也有效:

[[NSRunLoop currentRunLoop] acceptInputForMode:NSDefaultRunLoopMode beforeDate:nil];
于 2012-07-26T03:09:19.530 回答
0

所有与 UI 相关的事情都在主线程中完成。强制你的运行时在主线程上休眠将真正冻结你的 UI。这样做 180 次,你会得到一个沮丧的最终用户。

于 2012-07-26T04:09:16.660 回答