Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display time in seconds in Cocoa efficiently?

I want to display the time (including seconds) in an application in a text field, pretty simple. What I currently do is create a NSTimer that runs every 0.1 seconds that gets the system time and updates the text field. This seems like a terribly inefficient way to accomplish this. Is there a better way?

like image 974
rscott Avatar asked Nov 05 '09 01:11

rscott


2 Answers

Are you displaying it to tenth-of-a-second (or finer) resolution?

If so, I see no problem. Usually, polling sucks because what you're checking might not have changed, but it's not like time is going to stop on you. So a tenth-of-a-second timer is fine.

If not, create a timer whose interval is the desired resolution, then get its fire date, round it down to the desired resolution (e.g., a whole second if you update every second), and set that as the new fire date. Then, your timer will only fire coincidentally with the times it's appropriate to update your clock view.

Note that while time always moves, it doesn't always move linearly: it may jump ahead or backward by an hour or half an hour, or any amount if the user (or ntpd) changes the system clock setting. On Mac OS X 10.6 and later, you can observe for the NSSystemClockDidChangeNotification, and re-adjust your timer's fire date when that happens.

like image 53
Peter Hosey Avatar answered Oct 21 '22 05:10

Peter Hosey


How about you use NSTimer that runs every second and then you check the firing time and make sure it is exactly on the start of a second. You can use initWithFireDate:interval:target:selector:userInfo:repeats: or set the next invocation time appropriately using setFireDate: after the timer was created:

NSTimeInterval interval = [[timer fireDate] timeIntervalSinceReferenceDate];
NSTimeInterval nextFire = ceil(interval);
[timer setFireDate: [NSDate dateWithTimeIntervalSinceReferenceDate: nextFire];

Then you'll be sure that the timer fires as close to the needed time as possible and don't worry about the timer lagging behind because it resets itself after each firing using intended firing date and interval you provided, so it will always try to fire at exact second (but will fire whenever the run loop will be able to do that).

like image 34
inkredibl Avatar answered Oct 21 '22 06:10

inkredibl