Patricia
Patricia

Reputation: 289

Using a Static NSDate to determine passing time

I'm trying to set up a static-date to determine how many seconds have passed between each time I call this method.

Instant crash!

-(void) myMethod
{   
    static NSDate *staticDate = nil;
    NSTimeInterval seconds   = 0.0;

    if(staticDate)
    {   
        NSLog(@"%@", staticDate);
        seconds = [staticDate timeIntervalSinceNow];
    }

    staticDate = [NSDate date];
    NSLog(@"%.2f", seconds);
}

Upvotes: 5

Views: 1503

Answers (4)

You are not retaining the date you create - you really want:

staticDate = [[NSDate date] retain];

The static variable maintains a pointer and if you do not retain the pointer the memory is released and you point to nothing.

Upvotes: 0

NSGod
NSGod

Reputation: 22938

Try something like this:

-(void) myMethod
{   

     static NSDate *staticDate = nil;
     if (staticDate == nil) staticDate = [[NSDate date] retain];

     if(staticDate)
     {   
     NSTimeInterval elapsedTime = fabs([staticDate timeIntervalSinceNow]);
     NSLog(@"elapsedTime == %.7f sec (%.4f ms)",
                    elapsedTime, elapsedTime * 1000.0); 
     }
     [staticDate release];
     staticDate = [[NSDate date] retain];
}

Upvotes: 0

Jasarien
Jasarien

Reputation: 58448

Perhaps you'd be better of using timeIntervalSince1970, as its a commonly used method across many languages. It will return the number of seconds that have elapsed since the 1st January 1970.

Set up an instance variable to hold the first timeInterval and initialise it to the value returned by [[NSDate date] timeIntervalSince1970], then you could use it in your method like this:

-(void) myMethod
{
    NSTimeInterval seconds = [[NSDate date] timeIntervalSince1970] - _initialTimeInterval;
    NSLog(@"Seconds = %.2f", seconds);
}

A posible reason why your current code may crash is because [NSDate date] returns an autoreleased object. Even though the variable is static, the autorelease pool is likely releasing the date object and then causing a crash when you try to access it the next time the method is run.

You may be able to skirt around this crash if you create a new date or retain the one returned from date. However, assigning a retained/owned object to a static variable will result in a memory leak and I suggest you try my solution instead.

Upvotes: 7

James Bedford
James Bedford

Reputation: 28972

Does it crash at the following line?

NSLog(@"%.2f", seconds);

Because NSTimeInterval is a typedef for the double type, and your placeholder specifies a float.

Upvotes: 0

Related Questions