循环更改UILabel

时间:2011-02-18 14:19:52

标签: iphone xcode ios4

我想在循环中2秒后更改UILabel。 但是当前代码在循环结束后将其更改为最后一个值。

- (IBAction) start:(id)sender{


   for (int i=0; i<3; i++) {
    NSString *tempStr = [[NSString alloc] initWithFormat:@"%s", @" "];

    int randomNumber = 1+ arc4random() %(3);

    if (randomNumber == 1) {
        tempStr = @"Red";
    }else if (randomNumber == 2) {
        tempStr = @"Blue";
    } else {
        tempStr = @"Green";
    }
       NSLog(@"log: %@ ", tempStr);
       labelsText.text = tempStr;
       [tempStr release];
        sleep(2);

    }
}

3 个答案:

答案 0 :(得分:2)

您的代码仅在您的功能阻止主线程时将标签更新为最后一个值,因此UI无法更新。要解决该问题,请将更新代码移至单独的函数并使用performSelector:withObject:afterDelay:方法调用它。 (或使用NSTimer安排来电)

可能的解决方案(当用户连续多次点击按钮时,您还需要处理这种情况,但这不应该太困难):

- (IBAction) start:(id)sender{
    [self updateLabel];
}

- (void) updateLabel{
   static const NSString* allStrings[] = {@"Red", @"Blue", @"Green"};
   static int count = 0;

   int randomNumber = arc4random()%3;
   NSString *tempStr = allStrings[randomNumber];

   NSLog(@"log: %@ ", tempStr);
   labelsText.text = tempStr;

   ++count;
   if (count)
      [self performSelector:@selector(updateLabel) withObject:nil afterDelay:2.0];

}

答案 1 :(得分:0)

- (IBAction) start:(id)sender{
   for (int i=0; i<3; i++) {

    int randomNumber = 1+ arc4random() %(3);
    NSString *tempStr = @"";
    if (randomNumber == 1) {
        tempStr = @"Red";
    }else if (randomNumber == 2) {
        tempStr = @"Blue";
    } else {
        tempStr = @"Green";
    }
    [labelsText performSelector:@selector(setText:) withObject:tempStr afterDelay:i * 2]
       NSLog(@"log: %@ ", tempStr);
    }
}

答案 2 :(得分:0)

请勿在延迟后使用sleep()执行操作,它会阻止整个线程。请改用performSelector:withObject:afterDelay:。由于您可能在主线程上运行此命令,sleep()将阻止任何UI更新,直到整个循环运行之后,因此您唯一看到的是上次更新。作为一般经验法则,假设在应用程序完成方法执行之后,UI才会更新。

您不应该使用%s作为NSString的格式说明符,这是C字符串的格式说明符。您应该使用%@代替。事实上,如果您所做的只是使用NSString字面值初始化字符串,则根本不需要使用initWithFormat,您只需使用文字本身。

你也有很大的记忆问题。在循环开始时,您为NSString的实例分配内存,该实例是单个空格。然后,当您再次分配给tempStr时,覆盖指向此内存的指针,这意味着您泄漏了原始内存分配。 构建和分析会为您找到这样的问题。然后你释放tempStr,但是当这个指针变量的第二个赋值是自动释放的NSString时,当自动释放池被耗尽时,实例将被释放一次太多,这可能表现为在应用程序中稍后无法调试的崩溃。

我会做这样的事情:

- (void)showRandomColourAfterDelay {
    static NSUInteger count = 0;
    switch (arc4random()%3) {
        case 0:
            labelsText.text = @"Red";
        case 1:
            labelsText.text = @"Blue";
        case 2:
            labelsText.text = @"Green";
    }
    count++;
    if (count >= 3) return;
    [self performSelector:@selector(showRandomColourAfterDelay) withObject:nil afterDelay:3];
}

事实上,我可能会使用NSArray来保存颜色字符串,但这会涉及单个方法之外的更改,因此我坚持使用您的硬编码方法。

相关问题