views:

298

answers:

2
+1  Q: 

NSTimer Troubles

I am trying to run the code below but it keeps locking up my simulator after the "Tick" is written to the console. It never outputs "Tock" so my guess is that it has to do with the line "NSTimeInterval elapsedTime = [startTime timeIntervalSinceNow];" The IBactions are activated by buttons. timer and startTime are defined in the .h as NSTimer and NSDate respectively.

Can anyone tell me what I am doing wrong?

code:

- (IBAction)startStopwatch:(id)sender
{
    startTime = [NSDate date];
    NSLog(@"%@", startTime);
    timer = [NSTimer scheduledTimerWithTimeInterval:1 //0.02
                                             target:self
                                           selector:@selector(tick:)
                                           userInfo:nil
                                            repeats:YES];
}

- (IBAction)stopStopwatch:(id)sender
{
    [timer invalidate];
    timer = nil;
}

- (void)tick:(NSTimer *)theTimer
{
    NSLog(@"Tick!");
    NSTimeInterval elapsedTime = [startTime timeIntervalSinceNow];
    NSLog(@"Tock!");
    NSLog(@"Delta: %d", elapsedTime);
}

I have the following in the .h:

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {

    NSTimer *timer;
    NSDate *startTime;
}


- (IBAction)startStopwatch:(id)sender;
- (IBAction)stopStopwatch:(id)sender;
- (void)tick:(NSTimer *)theTimer;

@property(nonatomic, retain) NSTimer *timer;
@property(nonatomic, retain) NSDate *startTime;

@end
+3  A: 

Where you have:

startTime = [NSDate date];

You need:

startTime = [[NSDate date] retain];

Anything that is created with out an alloc, new, init will be auto-released (rule of thumb). So what is happening is you are creating the NSDate, assigning it to startTime, it's getting auto-released (destroyed), then you are trying to call timeIntervalSinceNow on an object that was fully released so it blows up.

Adding the retain increased the retain count so it still sticks around after the auto-release. Don't forget to manually release it when you're done with it though!

ACBurk
I updated the post with my .h code. Shouldn't the "nonatomic, retain" take care of the retain issue? Does it act differently from your method?
SonnyBurnette
It 'should', I'm not too familiar with @properties, but from what I've been able to undertand, it should. However in my tests, it doesn't. I suspect it is because doing "startTime = [NSDate date];" is directly accessing the object, not going through the setter property that is being synthesized (also, you are calling @synthesize, right?).My method does work though :-D
ACBurk
It's not accessing the object, it's assigning the object directly to the instance variable. That's where the problem lies; you're not going through the property.
Peter Hosey
+2  A: 

To take advantage of the @property you need to do: self.startTime = [NSDate date]

Leibowitzn
DOH! That makes perfect sense. Thanks for the follow up.
SonnyBurnette