如果触发new,如何取消之前的NSTimer

时间:2014-03-06 21:08:02

标签: ios nstimer

我尝试使用nstimer来显示/隐藏视图。

    @interface
        @property (nonatomic, retain)NSTimer *timer;
        UIView *view;
        @implementation
        view.hiden=YES;
        - (void)handleTap:(UITapGestureRecognizer *)sender{
        if([timer isValid)]{
timer.invalidate;///that gives me _EXC_BAD_ACCESS
}
        view.hiden=NO;
        timer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                     target:self
                                                   selector:@selector(targetMethod)
                                                   userInfo:nil
                                                    repeats:NO];


        }
        -(void)targetMethod{
        view.hiden=YES;
        }

如果您了解此代码的某些内容,则可以看到问题所在。如果我点击一次并等待3秒钟,那么一切都很好。但是如果我点击它并在1.5秒后再次点击,它应该制作另一个计时器盒并在3秒后隐藏它,但它会在1.5秒后隐藏它,因为旧的正在开火。

正如你所看到的,我试图使它无效但却给我错误。

那我怎么能以适当的方式摧毁它?

4 个答案:

答案 0 :(得分:2)

像这样:

- (void)timerFired:(id)sender {
    _timer = nil;
    // do thing here
}

- (IBAction)handleTap:(id)sender {
    [_timer invalidate];
    _timer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                              target:self
                                            selector:@selector(timerFired:)
                                            userInfo:nil
                                             repeats:NO];
}

- (void)dealloc {
    [_timer invalidate];
}

这里有一些关键的事情要做:

  • 在处理计时器触发的代码中,将实例变量设置为nil。
  • 在创建新计时器之前使旧计时器失效。
  • 在使计时器无效之前,请不要担心检查计时器的有效性。如果您遵循此技术,计时器将有效或为零。在nil上调用invalidate是完全安全的。
  • 你无需_timer使其无效并重新分配;这段代码都在主线程上。但是,如果您只是取消了计时器,那么就可以了。
    • 原因是此计时器已在runloop上安排。这保证了在runloop的下一次迭代之前它不会触发。在你返回之前,runloop不会迭代。
  • dealloc中,您应该使计时器无效。 (在viewDidDisppear:中执行此操作可能更合适;如果这样做,请确保在之后将其取消。)

答案 1 :(得分:0)

使用

[timer invalidate];

NSTimer

答案 2 :(得分:0)

//before firing a timer null it always
[timer invalidate];
timer=nil;

//now create a new instance of it
timer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                     target:self
                                                   selector:@selector(targetMethod)
                                                   userInfo:nil
                                                    repeats:NO];

答案 3 :(得分:0)

使计时器无效后,将属性设置为nil,以便下次通过它时,您不会毫无意义地抓住无效的计时器。