使用scheduledTimerWithTimeInterval添加时,NSTimer不会触发选择器

时间:2014-05-12 15:26:15

标签: ios nstimer

我有一个这样的代码段:

m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds
                                                       target:self
                                                     selector:@selector(activityIndicatorTimer:)
                                                     userInfo:nil
                                                      repeats:NO];

当我这样调用它时,在给定的timeOutInSeconds之后不会触发选择器。但是,如果我将其修改为如下所示,则选择器将被调用两次。

NSLog(@"Timer set");
m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds
                                               target:self
                                             selector:@selector(activityIndicatorTimer:)
                                             userInfo:nil
                                              repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:m_timer forMode:NSRunLoopCommonModes];

有人可以提出任何关于我可能做错的建议吗?

我正在使用XCode 5.1,并在7.1.1 iPhone 4S上构建

2 个答案:

答案 0 :(得分:36)

在主线程中调用此计时器:

dispatch_async(dispatch_get_main_queue(), ^{
   m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds
                                                   target:self
                                                 selector:@selector(activityIndicatorTimer:)
                                                 userInfo:nil
                                                  repeats:NO];
});

答案 1 :(得分:2)

创建计时器有3个选项,正如Apple在doc中所述:

  
      
  • 使用scheduledTimerWithTimeInterval:invocation:repeats:或   scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:课程   创建计时器并在当前运行循环中计划它的方法   默认模式。
  •   
  • 使用timerWithTimeInterval:invocation:repeats:或   timerWithTimeInterval:target:selector:userInfo:repeats:类方法   创建计时器对象而不在运行循环上安排它。 (后   创建它,您必须通过调用手动将计时器添加到运行循环   addTimer:forMode:相应NSRunLoop对象的方法。)
  •   
  • 分配计时器并使用。初始化它   initWithFireDate:interval:target:selector:userInfo:repeats:方法。   (创建后,必须手动将计时器添加到运行循环中   调用相应NSRunLoop的addTimer:forMode:方法   对象。)
  •   

您正在使用的方法已经安排了当前循环的计时器,您不应该安排另一次。在我看来,问题出在其他地方,尝试(使其变得容易)设置固定值而不是timeOutInSeconds 在特定延迟(不应重复)之后调用内容的最常用方法是使用dispatch_after:

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //YOUR CODE
    });

2是任意间隔(在这种情况下为2秒)。