objective-c - NSTimer falling more and more behind - ios

I have a NSTimer (running on main thread) that is supposed to go off every 0.02s. However, I notice that as memory usage start going up (the app captures a frame every tick and stores in an array) subsequent ticks begin to take more then 0.02s.
How can I solve this issue? I'm starting to think NSTimer is not suited for high-frequency tasks like this.

As the docs state,
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.
Since 100 milliseconds = .1 seconds and your timer is supposed to run every 0.02 seconds, your timer schedule is far shorter than the timer's effective resolution and so you timer can easily get out of sync.

Related

Use NSTimer for better validation of beacon

I have a program in SWIFT, that detects when a beacon or multiple beacons are out of range and based on
that it will perform something like saving some data into database and etc. Everything works well, however I do get lots of
false positive in a way that "didExitRegion" getting fired and few secs later "didEnterRegion" getting fired while I haven't been moved or etc.
I know this has lot to do with the tuning of the beacons and their qualities, but at this time I have come up with an alternative solution.
So I decided to use NSTimer to see if I am really off range or is it just a false positive that I am getting?
so when didExitRegion is getting fired, I start a NSTimer for 60 secs. If the 60 secs is up and didEnterRegion didn't get fire, then I know
I am really out of range and perform whatever data saving I need to do.
Otherwise if didEnterRegion is called within that 60 secs, then I'll assume it was a false positive and invalidate the
nstimer and not doing anything.
Everything works well as long as I am working with one beacon. The problem I have with timer is when multiple beacons go out of range.
lets say first beacon is out of range, so didExitRegion is getting fire and start the NSTimer
Let say 20 secs later second beacon is off range and again didExitRegion is getting fired and that one starts the NSTimer again.
Now my NStimer is all out of synch and at that time, things are not working correct and the NSTimer continuously start itself when 60 secs
is up and etc.
So my question is what is the work around this solution? How can I keep my nstimer in synch when is called again before is invalidated?
Is there a better way to this solution? Again, I know a better quality beacons can help, but that is not an option for me at this time.
One solution is to keep a dictionary like this:
var pendingExits = Dictionary<CLBeaconRegion,NSDate>()
Each time you get a didExitRegion call:
Only start the NSTimer if the dictionary is empty -- otherwise, assume the timer is already running.
Add the region to the dictionary along with a new NSDate() to set the timestamp of when it was added.
When you get a didEnterRegion callback:
Look for the region in the dictionary. If it is there, remove it.
When the timer goes off:
Look for any entry with a timestamp 60 seconds or more old. For this, remove the region from the dictionary and fire your custom exit logic.
Find the newest remaining timestamp (if any) in the dictionary. Start the timer to go off at that time plus 60 seconds.

dart timer periodic documentation is confusing

I have a long running task and I would like to schedule a new run a fixed interval after the run ends and I found this. What does the following mean? In particular the last paragraph.
Timer.periodic(Duration duration, Function void callback(Timer timer))
Creates a new repeating timer.
The callback is invoked repeatedly with duration intervals until
canceled with the cancel function.
The exact timing depends on the underlying timer implementation. No
more than n callbacks will be made in duration * n time, but the time
between two consecutive callbacks can be shorter and longer than
duration.
In particular, an implementation may schedule the next callback, e.g.,
a duration after either when the previous callback ended, when the
previous callback started, or when the previous callback was scheduled
for - even if the actual callback was delayed.
Let's say you set a timer to run every 30 seconds. If the second time the callback is called it takes 10 seconds to complete, the third call to the callback could be:
30 seconds after the second call started
30 seconds after the second call ended (which is 40s after the second call started, since it took 10 secs)
30 seconds after the second call was scheduled to run (which based on the above, could have been delayed, eg. by the duration of the first call)
Timer's duration is delay. Timer.periodic's duration is period.

Objective-C iPhone check location periodically

My iOS application relies heavily on GPS and I tried writing a method that helps conserve battery but I am having little success.
I created an NSTimer that fired every 15 seconds. Every time the method was called, it would increment an int time up by 1. If int time reached 20(5 minutes) it would turn off the location updates and set a bool isStopped to true. Every time the method ran and int time was above 20, it would increment another int, int time2, up by 1. If the method was ran and int time2 was equal to 4, it would start the location updates again and set time2 to 0.
Then in the didUpdateLocation: method for the location manager, I have an algorithm that would first check if the bool isStopped was true, if it was true then it would check the new location's horizontal accuracy and make sure it was under 10. Then it would check the newLocation with a location object named coords and check to see if they were greater than 9 meters apart. If they were not, it would stop location updates again and return. If they were, it would continue to another algorithm where it would check the new location object against some arguments. If it passed the coords location object would be set with the new location object, the time and time2 ints would be set to 0, the isStopped would be set to false, and the whole process would start all over again.
In short, after 5 minutes of no location changes, the location updates would be stopped and periodically checked every 1 minute to see if the user had moved at least 10 meters from the previous location that passed all requirements. When the user does move far enough, it starts the process all over again and the user has to not move 10 or more meters for 5 minutes before it starts the periodic checks. The thought behind this is to do only few second checks every minute when the user isn't moving much instead of constantly having the location services running.
Now here's the problem I run into, when the location updates stop. The NSTimer stops running while the app is in the background.
Could I somehow schedule a background task to run the loop between the 1 minute checks? Does anyone have any better ideas? Or any ideas on solutions to this?
A while ago I asked a question that features all the different ways that you can run GPS in the background.
CLLocationManager geo-fencing/startMonitoringForRegion: vs. startMonitoringForSignificantLocationChanges: vs. 10-minute startUpdating calls
You have to do specific things in order to maintain GPS in the background. A NSTimer would not suffice, since you need to register your app to be allowed to keep it running in the background after ten minutes. You minimally have to run the GPS every 10 minutes in the background to keep your app running.
Anyway, the methods in the above post should answer your question.

How to giva a time accurate timer in Fire Monkey?

I have to display a timer in 10th second for a sport competition. I have do this using the OnTimer event of a TTimer. the interval is set to 100. My routine display the current min:sec.10th (ex.: 02:45.7 ) correctly but it seem that my timer loose about 4 second at each minutes if I comp. to normal clock.
There is a better way to get a time accuracy timer in Delphi XE2 (or XE3) ?
You can use a timer to display the current value of the clock, but use a different approach to calculate the elapsed time.
You have to know that Windows timers are not time accurate, and even if you set it to elapse every 100 milliseconds, it can take more to fire the OnTimer event and even it can miss some intervals if for some reason elapses two or more times before your application process it.
You can, for example, use the system high-resolution performance counter to track times with nano-second accuracy.
You can also use the Delphi TStopwatch class, which encapsulates the system calls and falls back to other method (GetTickCount) if the high resolution performance counter is not available in your machine.
Take also a look at the How to Accurately Measure Elapsed Time Using High-Resolution Performance Counter delphi.about.com article.

Execute action every x seconds delphi

I'm trying to execute a function(or procedure) every x seconds.
I've been looking everywhere but never seemed to find something that suits my needs.
My application basically gets data from the web and I want to make an auto-refresh checkbox.
So let's say the user checks the box, I want the app to call that function every 5 seconds.
Thanks!
Use a TTimer (from the System tab in the component palette). Set the interval to the number of seconds * 1000 (converting from milliseconds to seconds), and write a handler for the OnTimer event.
The simplest way it to use the TTimer component, part of Delphi's standard VCL. Put one on the form, make sure Enabled is set to True, set Interval to 5000 (the value is in milliseconds), and assign its OnTimer event, where you'll put the code that needs to run every 5 seconds.
Sometimes it is a good idea to start with the timer disabled, then set its Enabled property to true in code, so that the timer starts to fire after everything else in your application has been properly set up.
The timer may not be firing in exact 5-second intervals, since timer messages have low priority in Windows and may not be received if the CPU is doing a lot of other work. Since your interval is relatively long, you might set the timer to fire every second (Interval := 1000) or even a few times per second, and check current time every time it fires. Perform the update if current time is later by 5 seconds or more from the time of the last update. (Use the SecondsBetween function in DateUtils unit to make that determination).
I don't have Delphi at the moment, but I'm pretty sure there was a TTimer component in the control palette, and according to this, I think I'm right.

Resources