0

Trying to record the time it takes for a user to press one button, and then the next.

Here's part of my .m file... I can't get theDate to hold its variable (The start time) All that happens is I get 0.000 seconds in the log & text label.

- (IBAction)start:(id)sender
{

    NSDate *theDate = [[NSDate date] init];

}

- (IBAction)stop:(id)sender
{
    NSTimeInterval timeInterval = [theDate timeIntervalSinceNow];
    NSString *time = [NSString stringWithFormat:@"%f", timeInterval];

    _timeLabel.text = time;
    NSLog(time);
}

I also have

@property(retain, nonatomic) NSDate *theDate;

in the header file and

@synthesize theDate;

in the top of the .m file.

Thanks!

BTW I'm trying to go off of this post: Getting the time elapsed (Objective-c)

Community
  • 1
  • 1
EpicDewd
  • 377
  • 1
  • 4
  • 8

3 Answers3

2
NSDate *theDate = [[NSDate date] init];

Creates a local variable so it doesn't use your property. In addition, as @Catfish_Man pointed out, [[NSDate date] init] should just be [NSDate date].

In addition, you should use self.theDate to use the property.

- (IBAction)start:(id)sender
{
    self.theDate = [NSDate date];
}

- (IBAction)stop:(id)sender
{
    NSTimeInterval timeInterval = [self.theDate timeIntervalSinceNow];
    NSString *time = [NSString stringWithFormat:@"%f", timeInterval];

    _timeLabel.text = time;
    NSLog(time);
}
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
1

You are redefining date with a local scope in

- (IBAction)start:(id)sender

You should be using

self.date = [NSDate date];
Naveed
  • 2,942
  • 2
  • 25
  • 58
1

You can get really fine timing (seconds.parts of seconds) using this StopWatch class. It uses the high-precision timer in the iPhone. Using NSDate will only get you second(s) accuracy.

StopWatch.h

#import <Foundation/Foundation.h>


@interface StopWatch : NSObject 
{
    uint64_t _start;
    uint64_t _stop;
    uint64_t _elapsed;
}

-(void) Start;
-(void) Stop;
-(void) StopWithContext:(NSString*) context;
-(double) seconds;
-(NSString*) description;
+(StopWatch*) stopWatch;
-(StopWatch*) init;
@end

StopWatch.m

#import "StopWatch.h"
#include <mach/mach_time.h>

@implementation StopWatch

-(void) Start
{
    _stop = 0;
    _elapsed = 0;
    _start = mach_absolute_time();
}
-(void) Stop
{
    _stop = mach_absolute_time();   
    if(_stop > _start)
    {
        _elapsed = _stop - _start;
    }
    else 
    {
        _elapsed = 0;
    }
    _start = mach_absolute_time();
}

-(void) StopWithContext:(NSString*) context
{
    _stop = mach_absolute_time();   
    if(_stop > _start)
    {
        _elapsed = _stop - _start;
    }
    else 
    {
        _elapsed = 0;
    }
    NSLog([NSString stringWithFormat:@"[%@] Stopped at %f",context,[self seconds]]);

    _start = mach_absolute_time();
}


-(double) seconds
{
    if(_elapsed > 0)
    {
        uint64_t elapsedTimeNano = 0;

        mach_timebase_info_data_t timeBaseInfo;
        mach_timebase_info(&timeBaseInfo);
        elapsedTimeNano = _elapsed * timeBaseInfo.numer / timeBaseInfo.denom;
        double elapsedSeconds = elapsedTimeNano * 1.0E-9;
        return elapsedSeconds;
    }
    return 0.0;
}
-(NSString*) description
{
    return [NSString stringWithFormat:@"%f secs.",[self seconds]];
}
+(StopWatch*) stopWatch
{
    StopWatch* obj = [[[StopWatch alloc] init] autorelease];
    return obj;
}
-(StopWatch*) init
{
    [super   init];
    return self;
}

@end

The class has a static stopWatch method that returns an autoreleased object.

Once you call start, use the seconds method to get the elapsed time. Call start again to restart it. Or stop to stop it. You can still read the time (call seconds) anytime after calling stop.

Example In A Function (Timing call of execution)

-(void)SomeFunc
{
   StopWatch* stopWatch = [StopWatch stopWatch];
   [stopWatch Start];

   ... do stuff

   [stopWatch StopWithContext:[NSString stringWithFormat:@"Created %d Records",[records count]]];
}

There is an equivalent version in C++ (for .mm or .cpp implementations) if you need it. You can find that here.

Even if you don't use the class specifically, the general technique will allow you to get high accurate time differences for events.

NOTE I could cache the mach_timebase_info_data_t if it is the first time and save the call to get it. This is older code and does not have that (minor) optimization.

FuzzyBunnySlippers
  • 3,387
  • 2
  • 18
  • 28