NSTimer不会停止

时间:2009-06-23 09:35:18

标签: iphone cocoa-touch timer

我有一个计时器,在调用viewWillAppear方法时触发,在调用viewDidDisappear方法时无效。但是在视图之间进行一定量的切换之后,计时器即使在无效之后也会继续触发。有什么问题?

这是我的代码:

NSTimer *timer;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f
                     target: self
                     selector:@selector( timerAction )
                     userInfo:nil
                     repeats:YES];
}

-(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [timer invalidate];
    timer = nil;
}

-(void) timerAction
{
    NSLog(@"timerAction");
}

12 个答案:

答案 0 :(得分:38)

我应该通过保留它来保持与计时器的链接。 :) 我在5个月前问过这个问题,这太棒了,我获得了多少经验。 :)

timer = [ [NSTimer scheduledTimerWithTimeInterval: ...] retain];
...
...
[timer invalidate];
[timer release];

答案 1 :(得分:14)

这是绝对的解决方案。以上都没有为我工作,所以我这样做了,

你想要启动计时器,

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO];

计时器调用的方法

-(void)timerMethod
{
    // do what you need to do

    if (needs to be called again) {

        [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO];        
    }
}

希望这有帮助,

答案 2 :(得分:6)

计时器调用的方法应具有定义

- (void)methodName:(NSTimer *)aTimer;

这种方法具有触发的计时器实例。你这样做的方法,该方法不知道计时器是否无效。

尝试将计时器初始化更改为

timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f target: self selector:@selector(timerAction:) userInfo:nil repeats:YES]

以及

的方法
-(void) timerAction:(NSTimer *)aTimer{...}

希望有所帮助

答案 3 :(得分:2)

这可能不是问题,但您需要保留对来自scheduledTimerWithInterval:的计时器的引用。如果不执行此操作,则在停止计时器时,指向计时器的指针可能无效。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    timer = [[NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(timerAction) userInfo:nil repeats:YES] retain];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [timer invalidate];
    [timer release];
    timer = nil;
    [super viewDidDisappear:animated];
}

- (void)dealloc
{
    [timer invalidate];
    [timer release];
    timer = nil;
    [super dealloc];
}

另外,尝试在viewDidDisappear中设置一个断点,并确保它被调用!

答案 4 :(得分:1)

**In .h class**

@interface 
{
NSTimer * theTimer;

}


**in .m class**

//put this code where you want to calling the NSTimer function

        theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];



- (void)updateCounter:(NSTimer *)theTimer 
{

   // write your code here for counter update 

}


// put this code to Stop timer:

    [theTimer invalidate];
    theTimer = nil;

答案 5 :(得分:1)

这在Swift中对我有所帮助

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    dispatch_async(dispatch_get_main_queue(),{ [weak self] in

        self?.idleTimer?.invalidate()
        self?.idleTimer = nil

    })

}

答案 6 :(得分:0)

您忘记在viewWillDisappear:

中释放计时器
- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [timer invalidate];
    [timer release];
    timer = nil;
}

这不应该导致计时器继续射击......

答案 7 :(得分:0)

invalidate doco表示

“运行循环会在invalidate方法返回之前或之后的某个时间点删除并释放计时器。”

我想你的东西会在稍后被删除。

答案 8 :(得分:0)

我遇到了同样的问题。

如果计时器仍然在运行,我无法解除我的实例,所以我必须在调用之前停止它:

- (void)stopTimer
{
    [timer invalidate];
    [timer release];
    timer = nil;
}

调用此方法后,我的计时器确实停止

答案 9 :(得分:0)

- (void)viewWillAppear:(BOOL)animated再次被召唤。

事实上,每次切换视图或解除模态视图后都会调用它。基本上任何时候你的视图实际上都会重新出现在屏幕上,而不仅仅是第一次。

因此,在这种情况下,计时器会重新启动,即使之前已经失效。

答案 10 :(得分:0)

创建计时器后,只需将其注册为NSRunLoopCommonModes

即可运行

[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];

然后invalidate方法就可以了。

答案 11 :(得分:0)

这对我有用

dispatch_async(dispatch_get_main_queue(), ^{
    [timer invalidate];
});