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 循环设为有限,代码仍会继续循环。我想要的是代码执行,暂停两秒钟,然后在int值小于loopLimit我设置的值时运行循环。

有人暗示这种performSelector:withObject:afterDelay:方法可能不适合在这里使用,但我不确定为什么或在这里使用什么更好。

有什么启发性的建议吗?

4

2 回答 2

3

这里发生的是循环以尽可能快的速度运行,并且performSelector:...调用以这种速度发生。然后,在 2.0001, 2.0004, 2.0010, ... 秒后,method被调用。

另一件事(现在您已经进行了编辑以明确performSelector:...最终调用与它所在的方法相同的方法,是循环index变量的值不会在调用之间保存。每次loopMethod运行时,代码循环从头开始:index设置为零并向上计数。这意味着每次运行该方法时,都会有loopLimit 新的调用挂起,从那时起 2 秒。这些调用中的每一个依次产生一个新集合,并且以此类推,无穷无尽。

循环的每次运行实际上都是有限的,但循环一直在运行。您需要某种方式来发出循环需要停止的信号,并且您不能完全在循环方法中执行此操作。您可以将计数器(您的index变量)放入 ivar;这将使其值在对 的调用中保持不变loopMethod,但我认为您想研究使用NSTimer重复的:

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

如果将其粘贴到 ivar 中,则可以跟踪它触发的次数并稍后停止。SO上有很多关于在循环中更新文本字段的帖子,使用这样的计时器:https ://stackoverflow.com/search?q=%5Bobjc%5D+update+text+field+timer

于 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 回答