当我打电话给[Timer isValid]或[Timer invalidate]时,NSTimer崩溃了

时间:2010-09-11 19:32:39

标签: iphone objective-c xcode crash nstimer

我的iPhone应用程序中有两个NSTimers。 DecreaseTimer工作正常,但是当我调用[timerCountSeconds isValid]或[timerCountSeconds invalidate]时,TimerCountSeconds崩溃。它们的用法如下:

-(id)initialize { //Gets called, when the app launches and when a UIButton is pressed
 if ([timerCountSeconds isValid]) {
  [timerCountSeconds invalidate];
 } 
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //Gets called, when you begin touching the screen
 //....
 if ([decreaseTimer isValid]) {
   [decreaseTimer invalidate];
  }
 timerCountSeconds = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
 //....
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {//Gets called, when you stop touching the screen(not if you press the UIButton for -(id)initialize)
 //...
 decreaseTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(decrease) userInfo:nil repeats:YES];
 //...
}
-(void)comept3 { //Gets calles when you rubbed the screen a bit
    if ([timerCountSeconds isValid]) {
    [timerCountSeconds invalidate];
    }
}

我做错了什么? 你能帮我吗?

5 个答案:

答案 0 :(得分:22)

您应NSTimer之后将nil对象设置为invalidate,因为invalidate方法调用也会执行release(根据Apple文档)。如果不这样做,请调用isValid之类的方法可能会导致崩溃。

答案 1 :(得分:3)

很可能存储在该变量中的计时器已被解除分配。如果你想保持它任意长时间,你需要保留它。

答案 2 :(得分:3)

 [objTimer retain];

然后它不会随时崩溃。在初始化计时器后使用它,这样它就能正常工作....

答案 3 :(得分:1)

您需要在主线程中设置计时器。 NSTimer不会在后台线程中被触发。

  • Objc:

    dispatch_async(dispatch_get_main_queue(), ^{
       _timer = [NSTimer scheduledTimerWithTimeInterval:delay target:self selector:@selector(YOUR_METHOD) userInfo:nil repeats:YES];
    });
    
  • 夫特:

    dispatch_async(dispatch_get_main_queue()) {
       timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: "YOUR_METHOD", userInfo: nil, repeats: true)
    }
    

答案 4 :(得分:0)

您需要在初始化时初始化TimerCountSecondsDecreaseTimer成员。假设您的控制流程为:

...
myObject = [[MyObject alloc] initialize];
...
[myObject touchesBegan:...]
...
[myObject touchesEnded:...]
...

然后当您致电initialize TimerCountSeconds时尚未初始化,那么您在逻辑上正在做

[<random pointer> isValid]

哪个会崩溃。同样,第一次调用touchesBegan时,DecreaseTimer无效。

在初始化方法中,在尝试使用任何内容之前,您需要实际初始化所有内容。

您似乎也在泄漏定时器(touchesBegin使定时器无效但不释放它)