0

このUITextViewの内容を、このNSMutable配列に遅延を追加して更新したいと思います。

- (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:dispatch_after()

特定の回数だけループして、これらのいずれかを内部で呼び出すことができると思う場合は、何か面白いものが表示されます。これらのメソッドは両方とも非同期であり、呼び出しが呼び出されるのを待ちません。彼らは単に「今」から指定された時間にそれが起こるようにスケジュールしているだけです。

非同期メソッドのループと呼び出しは何をしますか

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

この結果、ご想像のとおり、1秒間は何も起こりません。次に、スケジュールされたすべての通話が一度に発生します。

これは、実際には1秒後にループ全体を実行することと同じです。

 |----- 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];
}

これは繰り返しタイマーとまったく同じことをしますが、2つの主な欠点があります。

1)直感的ではありません。

タイマーの例では、テキストが毎秒更新されることを理解するためにタイマーコードを読むだけで済みます。この場合、を呼び出すだけupdateTextです。updateTextの実装を見ずにそのコードを読むことは、これが繰り返しのプロセスであることを直感的に理解することはできません。

2)停止したい場合は、さらに複雑になります。

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..グランドセントラルディスパッチもご利用いただけます。

于 2013-01-24T19:43:38.267 に答える