我想在循环中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);
}
}
答案 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
来保存颜色字符串,但这会涉及单个方法之外的更改,因此我坚持使用您的硬编码方法。