1

これは私が作業しようとしているコードスニペットですが、そのループは私が望む方法で停止しません:

 - (IBAction)methodName:(UIButton*)sender 
{
        [self loopMethod];
}

-(void) loopMethod
{

   for( int index = 0; index < loopLimit; index++ ) 
   {
        //code I want to execute
        [self performSelector:@selector(loopMethod) 
                   withObject:nil 
                   afterDelay:2.0];   
   }
}

for ループを有限にしたにもかかわらず、コードはループし続けます。私が望むのは、コードを実行し、2 秒間一時停止してから、値が設定したint値よりも小さい間にループを実行するloopLimitことです。

このperformSelector:withObject:afterDelay:方法はここで使用するのが適切ではない可能性があることがほのめかされていますが、ここで使用する方が良い理由や方法はわかりません。

明るい提案はありますか?

4

2 に答える 2

3

ここで起こっていることは、ループが可能な限り速く実行され、performSelector:...呼び出しがその速度で行われているということです。次に、2.0001、2.0004、2.0010、... 秒後にmethod呼び出されます。

performSelector:...もう 1 つは (これで、 が含まれているのと同じメソッドを呼び出すことになることを明確にするために編集したので、ループのindex変数の値が呼び出し間で保存されないことです。実行されるたびloopMethodに、ループは最初から始まります:indexはゼロに設定され、カウントアップします. つまり、メソッドが実行されるたびに、その2 秒後に保留中のloopLimit 新しい呼び出しが発生します. これらの呼び出しのそれぞれが順番に新しいセットを生成し、など、無限に。

ループのすべての実行は実際には有限ですが、ループは実行され続けます。ループを停止する必要があることを知らせる何らかの方法が必要ですが、ループ メソッド内で完全にそれを行うことはできません。カウンター (index変数) を ivar に入れることができます。これにより、 の呼び出し間でその値が永続化されますが、繰り返すを使用するloopMethodことを検討したいと思います。NSTimer

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

これを ivar に貼り付ければ、発火回数を追跡して後で停止できます。次のようなタイマーを使用して、ループ内のテキスト フィールドを更新することについて、SO には既に多くの投稿があります。

于 2012-03-05T20:49:52.547 に答える
2

2 秒ごとに実行されない理由は、ループを実行していて、2 秒遅れてそのセレクターを撃ち落としているためです。つまり、ループ間に遅延はありません。私が推測しなければならなかった場合、それはおそらく2秒待ってから数loopLimit回起動しますよね?

関数が思いどおりに機能するには、再帰的である必要があります。

-(void) methodName
{
   if(index < loopLimit) {
    //code you want to execute
    [self performSelector:@selector(**methodName**) withObject:nil afterDelay:2.0];   
   }
   index++;
}

これはかなり厄介な方法です。AnNSTimerは通常、代わりにここで使用するものであり、完了したらタイマーを停止できます。

関数では、次のようにタイマーを開始します。

[self setIndex:0];
[self setTimer:[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(method:) userInfo:nil repeats:YES]];

次に、このメソッドが毎回呼び出されます。

-(void)method:(NSTimer *)timer {
    if(index >= loopLimit) {
         [[self timer] invalidate];
    }

    //Code you want to execute
}
于 2012-03-05T20:56:03.330 に答える