NSTimer scheduled on main queue is sometimes firing with a delay

I am using the following methods to start and stop a NSTimer to initiate some heartbeat call.

I wait for the response of the call to initiate the timer again with the received timer Interval is seconds from the Response.

However, I am seeing that sometimes the actual time the timer method is called and the selector method is called with a delay.

The seconds value is usually 5 seconds and the delay is usually 1 to 10 seconds.


I see that if user is doing some scrolling continuously, it is also affecting the timer. so, I am guessing the UI job has higher priority than the timer and it is blocking the nstimer. Is there a way have the timer fired at exact time interval (upto 1 second delay is fine) ?

please let me know,


Thanks,

Kapil


-(void)startHeartBeatWithTime:(NSNumber *)aSeconds{

float seconds = [aSeconds integerValue];

dispatch_async(dispatch_get_main_queue(), ^{

self.heartBeatTimer = [NSTimer scheduledTimerWithTimeInterval:seconds

target:self

selector:@selector(initiateHeartbeatCall:)

userInfo:nil

repeats:NO];

NSLog(@"%@", [NSDate date]);


});

}


- (void)initiateHeartbeatCall:(NSTimer *)timer{

NSLog(@"%@", [NSDate date]); // doesn't always gets fired with the scheduled time.

}


-(void)stopHeartBeat{

dispatch_async(dispatch_get_main_queue(), ^{

[self.heartBeatTimer invalidate];

self.heartBeatTimer = nil;

});

}

Replies

When you schedule a timer like this it is scheduled in the default run loop mode (

NSDefaultRunLoopMode
). UI frameworks typically do event tracking in a custom run loop mode (the actual mode varies by platform). If you want your timer to fire i such modes, schedule it using the common modes placeholder (
NSRunLoopCommonModes
).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"