Search code examples
iphoneobjective-ctimernsdatenstimer

How Do I write a Timer in Objective-C?


I am trying to make a stop watch with NSTimer.

I gave the following code:

 nst_Timer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(showTime) userInfo:nil repeats:NO];

and it is not working in milliseconds. It takes more than 1 millisecond.


Solution

  • Don't use NSTimer that way. NSTimer is normally used to fire a selector at some time interval. It isn't high precision and isn't suited to what you want to do.

    What you want is a High resolution timer class (using NSDate):

    Output:

    Total time was: 0.002027 milliseconds
    Total time was: 0.000002 seconds
    Total time was: 0.000000 minutes
    

    Main:

    Timer *timer = [[Timer alloc] init];
    
    [timer startTimer];
    // Do some work
    [timer stopTimer];
    
    NSLog(@"Total time was: %lf milliseconds", [timer timeElapsedInMilliseconds]);  
    NSLog(@"Total time was: %lf seconds", [timer timeElapsedInSeconds]);
    NSLog(@"Total time was: %lf minutes", [timer timeElapsedInMinutes]);
    

    Edit: Added methods for -timeElapsedInMilliseconds and -timeElapsedInMinutes

    Timer.h:

    #import <Foundation/Foundation.h>
    
    @interface Timer : NSObject {
        NSDate *start;
        NSDate *end;
    }
    
    - (void) startTimer;
    - (void) stopTimer;
    - (double) timeElapsedInSeconds;
    - (double) timeElapsedInMilliseconds;
    - (double) timeElapsedInMinutes;
    
    @end
    

    Timer.m

    #import "Timer.h"
    
    @implementation Timer
    
    - (id) init {
        self = [super init];
        if (self != nil) {
            start = nil;
            end = nil;
        }
        return self;
    }
    
    - (void) startTimer {
        start = [NSDate date];
    }
    
    - (void) stopTimer {
        end = [NSDate date];
    }
    
    - (double) timeElapsedInSeconds {
        return [end timeIntervalSinceDate:start];
    }
    
    - (double) timeElapsedInMilliseconds {
        return [self timeElapsedInSeconds] * 1000.0f;
    }
    
    - (double) timeElapsedInMinutes {
        return [self timeElapsedInSeconds] / 60.0f;
    }
    
    @end