Reputation: 523
I have a NSTimer that works fine and counts down in 1 second intervals. But I want the timer to trigger immediately without that 1 second delay.
I thought calling [timer fire]
should work for this (described here) but it doesn't make a difference. I want the timer to be triggered as fast as if I scheduled the interval to be 0.
- (void)onStartButtonPressed:(UIButton*)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:tv];
NSIndexPath* indexPath = [tv indexPathForRowAtPoint:buttonPosition];
NSInteger index = indexPath.row;
// starts timer for cell at the index path
if (indexPath != nil)
{
NSTimer* timer = [timerArray objectAtIndex: index];
if ([timer isEqual:[NSNull null]]) {
NSLog(@"It's empty");
// start timer
NSTimer timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(onTick:)
userInfo:indexPath
repeats:YES];
// [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
NSLog(@"before timer fire");
[timer fire];
// update data array of timer objects and countdowns
NSInteger selectedTimeIdx = [[selectedTimeIdxArray objectAtIndex: index] integerValue];
NSInteger selectedTime = [pickerTimeArray[selectedTimeIdx] integerValue];
[timerArray replaceObjectAtIndex:index withObject:timer];
[countdownArray replaceObjectAtIndex:index withObject:[NSNumber numberWithInteger:selectedTime*60]];
} else {
NSLog(@"It's not empty");
}
}
- (void)onTick:(NSTimer *)timer
{
NSLog(@"on tick method starts");
// get the timer's owner's index path and update label
NSIndexPath* indexPath = [timer userInfo];
NSInteger index = indexPath.row;
// update countdown
NSInteger countdown = [[countdownArray objectAtIndex: index] integerValue];
[countdownArray replaceObjectAtIndex:index withObject:[NSNumber numberWithInteger:--countdown]];
// NSLog(@"countdown: %ld", (long)countdown);
[tv reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
// NSLog(@"Tic indexPath: %@", indexPath);
if (countdown == 0)
{
[timer invalidate];
timer = nil;
}
}
The timer works but I don't want there to be a 1 second delay for it to be initially triggered. I want the timer to start immediately.
Edit: I added logs that rmaddy suggested. Here are my results (I changed the interval time to 3):
2015-05-19 14:41:02.827 restaurant[4206:77915] before timer fire
2015-05-19 14:41:02.827 restaurant[4206:77915] on tick method starts
2015-05-19 14:41:05.827 restaurant[4206:77915] on tick method starts
2015-05-19 14:41:08.828 restaurant[4206:77915] on tick method starts
Upvotes: 0
Views: 604
Reputation: 523
Some of the comments were really helpful, especially adding the logs as suggested by rmaddy. It turns out [timer fire]
was working fine.
I had confused myself because my timerLabel
which displayed the countdown was being updated in my cell with a 1 second delay, and I thought that meant the timer instantiation was delayed.
Once I saw what the problem really was, all I had to do was update the cell in the same block that I instantiated the timer (instead of just onTick
).
I just added this to my onStartButtonPressed
and everything works as I want it to.
// update countdown
NSInteger countdown = [[countdownArray objectAtIndex: index] integerValue];
[countdownArray replaceObjectAtIndex:index withObject:[NSNumber numberWithInteger:--countdown]];
// cell label gets updated right at start button press
[tv reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
Leaving here in case it helps anyone.
Upvotes: 0
Reputation: 2064
Why not just call your method before the timer
[self onTick:nil];
//usual timer code here
Edit: as stated by rmaddy
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(onTick:)
userInfo:indexPath repeats:YES];
[self onTick:timer];
Upvotes: 1