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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to