Reputation: 1941
The following method causes a crash. The UI is like a button, which handles the start / stop functionality of the NSTimer. If the timer runs, a UILabel is updated. Using the viewDidLoad Method makes my timer work, stopping it works too, but starting it again crashes the app.
Removing the alloc in the viewDidLoad method and trying to use the start button causes a crash instantly. Even the NSLog(@"Start now");
is not called.
Code:
- (void)tick {
NSLog(@"tick");
float value = [moneyLabel.text floatValue];
moneyLabel.text = [NSString stringWithFormat:@"%f", value + 1.0];
}
- (IBAction)startStopButtonClicked:(UIButton *)sender {
if ([sender.titleLabel.text isEqualToString:@"Start"]) {
NSLog(@"Start now");
if (timer) {
NSLog(@"Timer valid");
[timer fire];
} else {
NSLog(@"Timer is nil");
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick) userInfo:nil repeats:YES];
[timer fire];
}
NSLog(@"bla");
[sender setTitle:@"Stop" forState:UIControlStateNormal];
} else {
[timer invalidate];
timer = nil;
NSLog(@"Stopped.");
NSLog(@"Timer isValid: %@", timer);
[sender setTitle:@"Start" forState:UIControlStateNormal];
}
}
Upvotes: 0
Views: 1364
Reputation: 15213
The code you have posted works as desired - just tested it in a new project, so the problem could be somewhere else. I tested it only by declaring the ivar NSTimer *timer;
without any initialization in viewDidLoad:
or the designated initializers...
Upvotes: 0
Reputation: 122391
I don't see the need to call [NSTimer fire]
at all; it should be enough to allow the timer to decide when to fire.
Firstly ensure that timer
is nil
(it should be if it's an instance variable of the object), although explicitly setting it to nil
in - (id)init
won't hurt.
Next I would use the state of the timer itself to determine whether start/stop has been pressed, not the text in the button:
- (IBAction)startStopButtonClicked:(UIButton *)sender
{
if (timer != nil)
{
NSLog(@"Stopping timer");
[timer invalidate];
timer = nil;
}
else
{
NSLog(@"Starting timer");
timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(tick)
userInfo:nil
repeats:YES];
}
[sender setTitle:(timer != nil ? @"Stop" : @"Start")
forState:UIControlStateNormal];
}
Upvotes: 3