Schedule timer with NSTimer makes the task run faster than expected
I schedule a timer with NSTimer's function in viewWillAppear
as follows:
minutesTimer = nil;
minutesTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(updateScrollViewItems) userInfo:NULL repeats:YES];
With this function call, I expect it to call the selector updateScrollViewItems
every minute, but it does not, it update items faster than expected (around some seconds).
What is the cause 开发者_Python百科of this unexpected behavior?
It might not be the direct cause of the issue you're seeing, but I can already spot one major error.
The fact that this timer is set up each time on viewWillAppear
means that whenever your view appears, you're creating a new timer (and leaking the old one) which will fire 60 seconds after creation.
If your view disappears and reappears multiple times, you're going to have multiple timers all firing the same method at completely random intervals.
You need to manage the timer properly. If you want it to start when the view is first created and keep ticking/firing even when the view is not shown, then you need to create it during init
, or viewDidLoad
, and then be sure to stop it when you dealloc
or viewDidUnload
.
If you want your timer to only tick/fire when the view is the current view, then you need to ensure you're managing stopping and starting the timer appropriately on viewDidAppear
and viewWillDisappear
.
Also, as Williham Totland said in his answer, NSTimer shouldn't be relied upon for exact timing. This is also stated in the documentation:
A timer is not a real-time mechanism; it fires only when one of the run loop modes to which the timer has been added is running and able to check if the timer’s firing time has passed. Because of the various input sources a typical run loop manages, the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. If a timer’s firing time occurs while the run loop is in a mode that is not monitoring the timer or during a long callout, the timer does not fire until the next time the run loop checks the timer. Therefore, the actual time at which the timer fires potentially can be a significant period of time after the scheduled firing time.
In this case, with a time span of 60 seconds, it shouldn't be a problem that the timer is not exact, I think the issues you're seeing are because the timer isn't being managed properly.
The iPhone is a lot of things; and a neat device, however; just like any other computer, a precision timepiece it is not. However, it seems as if the method in question takes an NSTimeInterval, which is a double. You might want to change that to 60.0
.
If you want your timer to only tick/fire when the view is the current view, then you need to ensure you're managing stopping and starting the timer appropriately on viewDidAppear and viewWillDisappear.
Thanks for this info, even though I'm not the OP of this thread I was looking for an answer for a similar issue. I was scratching my head for few days, searched all over the internet but I couldn't find the answer. Finally I found this thread. This is a valuable info for me.
精彩评论