【问题标题】:Why does my NSTimer double decrement my timer?为什么我的 NSTimer 双倍递减我的计时器?
【发布时间】:2014-12-09 00:47:39
【问题描述】:

我已经盯着我的代码看了好几个小时了,所以我想我可以试着来这里看看新的眼睛。我需要创建一个计时器,所以我使用下面的代码来做到这一点。第一行是我创建计时器的地方,第二部分是我的 decrementTime 方法。这是用于 IOS 应用程序的 Objective C 中的。这是我第一次在 StackOverflow 上发帖(我通常会找到我正在寻找的答案),所以请让我知道我不遵守的任何不成文的规则。

_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(decrementTime) userInfo:nil repeats:YES];

- (void)decrementTime{
       self.timeLeft--;
}

我将在此处添加使第一个计时器无效的位置

-(IBAction)infoClick:(id)sender{
       [_timer invalidate];   
}

然后这里是信息消息,我在其中创建另一个计时器

- (void)hideInfoMessage {  
     _secondTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(decrementTime) userInfo:nil repeats:YES];
}

澄清我的代码:事件的顺序从我的第一个代码块(创建计时器)开始。然后调用我的第二个代码块(使计时器无效)。然后最后我的第三个代码块被调用(创建一个新的计时器)。

我知道它是双倍递增,因为当我运行代码时,我可以直观地看到计时器双倍递增。

【问题讨论】:

  • FWIW,这里没有“不成文”的规则 - 请查看常见问题解答,了解您需要了解的所有内容(以及更多内容)。祝你好运
  • 你怎么知道它被双倍递减?
  • 尝试将NSLog(@"%s",__FUNCTION__); 添加到您的decrementTime,以便每次调用时都能看到
  • 根据您的更新代码,您正在创建两个不同的计时器并且都指向同一个选择器。这可以解释双倍递减。
  • @rmaddy 很抱歉我仍然有点困惑。当我使第一个计时器无效时,它不再存在了吗?

标签: ios objective-c timer


【解决方案1】:

调用两次创建计时器的代码非常容易。当你这样做时,你实际上有 2 个计时器同时运行。每一个都会递减你的值,所以它会每秒递减两次。

例如,如果您在 viewWillAppear 方法中创建了一个计时器,那么您需要在 viewWillDisappear 方法中使其无效,以确保您只有一个正在运行。

同样的方法适用于您创建计时器的其他情况。您需要确保平衡每个创建计时器的调用与使该计时器无效的调用。

如果您使用 scheduleTimer... 方法之一,您可以保存指向计时器的弱指针。只要它正在运行,运行循环就会保留它。当您使其无效时,系统运行循环将释放它并释放它。发生这种情况时,您的弱指针将归零,因此您甚至不必在 viewWillAppear 方法中对其进行测试以查看它是否有效/无。

编辑:

您需要检测您的代码。在您的 infoClick 方法中,变量 _timer 为零吗?它的地址是什么?

顺便说一句,NSTimer 的目标应该是一个采用单个参数的方法,即计时器本身。您应该将您的 decrementTime 方法更改为如下所示:

- (void) decrementTime: (NSTimer *) timer
{
  NSLog(@"In method decrementTime, timer = %X", (unsigned long) timer)
  self.timeLeft--;
}

然后查看您的日志,看看您的 decrementTime 方法是否被 2 个不同的计时器调用(我敢打赌它是。)

您可能还想记录您从调用 scheduleTimerWithTimeInterval 中获得的计时器地址...

【讨论】:

  • 好答案。此外,OP 在计时器上没有显示终止条件。与其减少剩余时间,不如计算未来计时器应该结束的时间,保存并将其与计时器触发时的当前时间进行比较。
  • 感谢您的回答。是的,我虽然这也是一个问题。但我创建另一个计时器的唯一时间是当我暂停游戏时。我使第一个计时器无效并创建一个新计时器。
  • @SteveCohen 只是为了确定,将 _timer 无效的行放在分配它的行之前。
  • 明确说明问题的两端,并在上下文中提供代码。你用什么方法创建定时器,用什么方法使它无效?你确定电话是平衡的吗?尝试在这两个地方添加日志语句,然后查看日志。我提供一个小赌注,您不会总是在创建新的之前将其无效。
  • 这就是让我发疯的原因。当我再次使其无效时,计时器停止。
猜你喜欢
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 2016-01-29
相关资源
最近更新 更多