Re: StopWatch Application Help
Re: StopWatch Application Help
- Subject: Re: StopWatch Application Help
- From: Marco Masser <email@hidden>
- Date: Sun, 20 Jul 2008 22:33:31 +0200
Thanks. That solved many issues.
However, I still have another question.
How about if I wanted the Timer to start at from 0, and then go to
1, 2, 3, etc..., not from January 1st like -
timeIntervalSinceReferenceDate does? I tried doing
timeIntervalSinceDate:, but it wouldn't work, and
timeIntervalSinceNow doesn't work either!
Actually, you shouldn't care about which time the timer uses as its
internal date. What you do care about is the time from the creation of
the timer until "now", whereas "now" is the time at which your UI
update method is called. Therefore, you just need the difference
between "now" and "then", you don't care about the actual values of
"now" and "then". Therefore, they both use a reference date, which is
the reason why NSTimer provides a method called
+timeIntervalSinceReferenceDate.
I revised my code, and it now looks like this:
<snip>
- (IBAction)startWatch:(id)sender
{
NSDate *currentDate = [NSDate date];
timer = [NSTimer timerWithTimeInterval:1 target:self
selector:@selector(updateTextfield:) userInfo:nil repeats: YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:
NSDefaultRunLoopMode];
[timer setFireDate:currentDate];
}
Again, you don't have to add the timer to the run loops in your case.
The Timer Reference specifically states:
The following two class methods automatically register the new timer
with the current NSRunLoop object in the default mode
(NSDefaultRunLoopMode).
scheduledTimerWithTimeInterval:invocation:repeats:
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
(http://developer.apple.com/documentation/Cocoa/Conceptual/Timers/Tasks/createtimer.html#/
/apple_ref/doc/uid/20000807)
- setFireDate: sets the date at which your timer fires. I don't know
about the implementation details of NSTimer, but I think setting it to
the current date will prevent it from firing at all because this date
*will* never be reached (it *has been* reached). In your application,
you do not want to set the fire date manually, you simply want your
timer to fire every second. Remove that line, or it won't work.
- (void)updateTextfield:(NSTimer *)timer
{
NSTimeInterval now =[NSDate timeIntervalSinceReferenceDate];
NSTimeInterval startTime;
NSTimeInterval difference = now - startTime;
NSString *timeString = [NSString stringWithFormat:@"%f", difference];
[textField setStringValue:timeString];
}
startTime should be an ivar, declaring it every time this method is
executed and not assigning it any value will yield unexpected results.
Simply declaring a variable of a primitive data type without an
assignment will give you some random number.
Again, to your first question: This is where you calculate how long
your stop watch is running already. You only need the difference
between "now" and "then", whereas "then" is the time at which your
timer started. Therefore, you must remember that time in -startWatch:
- (IBAction)stopWatch:(id)sender
{
[timer invalidate];
[timer release];
}
I forgot to mention this in my last mail: "timer" is released here,
but it is never retained by your code. Honestly, I forgot about the
memory management of timers, I had to read that up again (see the link
above, its right on that page). Because the run loop retains the
timer, you can actually remove the -release in -stopWatch:. You could
also retain it in -startWatch:, just make sure the number of -alloc/-
retain/-copy and -release messages match.
Additionally, add [timer invalidate] to your -windowWillClose or -
dealloc method to make sure the timer is stopped and removed from the
run loop.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden