在for()循环中更新UILabel

joh*_*ers 5 objective-c

我有一个带for()循环的方法.在该循环中,mylabel.text会多次更新.但是,在方法完成之前,实际标签不会在屏幕上更新,并使用for()循环中创建的最后一个值进行更新.

使用NSLog,它在for()循环的中间进行更新,我看到标签的值确实多次改变.

iOS中的一般做法是不在for()循环中更新标签吗?我想有办法做到这一点.

Mor*_*ast 14

您可以通过告诉运行循环如下运行来进行UI更新:

for (NSInteger i = 0; i < 10; i++) {
    [label setText:...];
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这可能会产生各种奇怪的副作用.当你调用`runMode:beforeDate:`时,各种各样的事情都可能发生在你的循环中.定时器可以开火; WebKit可以做各种疯狂; 延迟选择器可以发射.这是一个非常危险的伎俩.有时是有用的,有时是必要的(特别是在Mac上),但不是通用工具. (2认同)

Rob*_*ier 8

从我之前的评论:

请注意,this(runMode:beforeDate:)可能会产生各种奇怪的副作用.当你调用runMode:beforeDate:时,你的循环中间可能会发生各种各样的事情.定时器可以开火; WebKit可以做各种疯狂; 延迟选择器可以发射.这是一个非常危险的伎俩.有时是有用的,有时是必要的(特别是在Mac上),但不是通用工具.

更好的解决方案是在主调度队列上安排更新:

  for (NSInteger i = 0; i < 10; i++) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, i * NSEC_PER_SEC), 
                   dispatch_get_main_queue(), ^{
      [self.label setText:[NSString stringWithFormat:@"%d", i]];
    });
  }
Run Code Online (Sandbox Code Playgroud)

这将安排10次更新1秒.它可以适应各种其他要求,而无需在主运行循环上创建阻塞方法.