0

我想通过添加一些延迟来用这个 NSMutable 数组更新这个 UITextView 的内容。

- (void)viewDidLoad{
 [super viewDidLoad];
myArray = [[NSMutableArray alloc]initWithObjects:@"String1",@"String2",@"String3",@"String4", @"String5",..... nil];                                                                                                                                        



int index = arc4random() % [myArray count];

myTextView.text = [myArray objectAtIndex:index];

我想在 UITextView 中一个接一个地显示这个 NSMutable 数组。

有什么方法可以在 UITextView 中显示数组,但会有一些延迟。

请帮忙

4

2 回答 2

3

为什么你应该使用计时器

这样做的正确方法是使用重复计时器。计时器被配置为每秒重复并调用某个方法。

[NSTimer scheduledTimerWithTimeInterval:1.0
                                 target:self
                               selector:@selector(updateText:)
                               userInfo:nil
                                repeats:YES];

在您的(新)updateText方法中,您将生成随机数并更新文本。

- (void)updateText:(NSTimer *)theTimer {
    int index = arc4random() % [myArray count];
    myTextView.text = [myArray objectAtIndex:index];
}

这是一个几乎是自我记录的干净解决方案。


为什么你不应该在延迟后循环和执行。

确实可以performSelector:withObject:afterDelay:使用or来执行此操作,dispatch_after()但它很容易出错,并且实际的工作解决方案更复杂且更难理解。

如果你认为你可以循环一定次数并在内部调用其中任何一个,那么你会看到一些有趣的东西。这两种方法都是异步的,不会等待调用被调用。他们只是安排它从“现在”开始的指定时间发生。

循环和调用异步方法的作用

Loop 
 0    |----- 1s wait -----| |update|
 1     |----- 1s wait -----| |update|
 2      |----- 1s wait -----| |update|
 3       |----- 1s wait -----| |update|
    ...
 ----------- time --------------------->

可以想象,这样做的结果是一秒钟内什么都不会发生。然后所有预定的呼叫将同时发生。

这实际上等于在一秒钟后执行整个循环。

 |----- 1s wait -----| Loop:
                         0  |update|
                         1   |update|
                         2    |update|
                         3     |update|
                            ...
 ----------- time --------------------->

如果您改为在每次更新后安排下一次通话,您就可以完成这项工作

 |----- 1s wait -----| |update| |----- 1s wait -----| |update| ...
 ----------- time --------------------->

为此,您必须在上一次更新中安排下一次更新。

- (void)updateText {
    int index = arc4random() % [myArray count];
    myTextView.text = [myArray objectAtIndex:index];
    [self performSelector:@selector(updateText) 
               withObject:nil
               afterDelay:1.0];
}

这将做与重复计时器完全相同的事情,但有两个主要缺点。

1)它不太直观。

在计时器示例中,您只需阅读计时器代码即可了解文本每秒更新一次。在这种情况下,您只需调用updateText. 通过阅读该代码而不查看 updateText 的实现是不直观的,这是一个重复的过程。

2)如果你想让它停止,它会变得更加复杂。

您可以保留一个指向 an 的指针,NSTimer并通过简单地调用来使其停止[myTimer invalidate];。使用performSelector:...dispatch_after()尚不支持它的代码,如果它是为了支持它而构建的,它将更加复杂和不直观。

于 2013-01-24T20:53:47.300 回答
2

几种方法,根据我的喜好排列答案:

1..您可以使用:

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats

2.. Grand Central Dispatch也将为您服务。

于 2013-01-24T19:43:38.267 回答