Objective-C - NSTimer Usage
References
- http://developer.apple.com/library/ios/#Documentation/Cocoa/Conceptual/Timers/Articles/usingTimers.html
- https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Timers/Timers.html
- https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html
performSelector:withObject:afterDelay:
Invokes a method of the receiver on the current thread using the default mode after a delay.
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
Parameters aSelector A selector that identifies the method to invoke. The method should not have a significant return value and should take a single argument of type id, or no arguments. anArgument The argument to pass to the method when it is invoked. Pass nil if the method does not take an argument. delay The minimum time before which the message is sent. Specifying a delay of 0 does not necessarily cause the selector to be performed immediately. The selector is still queued on the thread’s run loop and performed as soon as possible. Discussion This method sets up a timer to perform the aSelector message on the current thread’s run loop. The timer is configured to run in the default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and perform the selector. It succeeds if the run loop is running and in the default mode; otherwise, the timer waits until the run loop is in the default mode.
If you want the message to be dequeued when the run loop is in a mode other than the default mode, use the performSelector:withObject:afterDelay:inModes: method instead. If you are not sure whether the current thread is the main thread, you can use the performSelectorOnMainThread:withObject:waitUntilDone: or performSelectorOnMainThread:withObject:waitUntilDone:modes: method to guarantee that your selector executes on the main thread. To cancel a queued message, use the cancelPreviousPerformRequestsWithTarget: or cancelPreviousPerformRequestsWithTarget:selector:object: method.
- (NSTimer*)createTimer { // create timer on run loop return [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTicked:) userInfo:nil repeats:YES]; } - (void)timerTicked:(NSTimer*)timer { // decrement timer 1 … this is your UI, tick down and redraw [myStopwatch tickDown]; [myStopwatch.view setNeedsDisplay]; // increment timer 2 … bump time and redraw in UI … } - (void)actionStop:(id)sender { // stop the timer [myTimer invalidate]; }
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(targetMethod:) userInfo:nil repeats:NO]; [myTimer invalidate]; myTimer = nil;\ NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self selector:@selector(onTick:) userInfo: nil repeats:NO]; [self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0]; NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0]; NSTimer *t = [[NSTimer alloc] initWithFireDate: d interval: 1 target: self selector:@selector(onTick:) userInfo:nil repeats:YES]; NSRunLoop *runner = [NSRunLoop currentRunLoop]; [runner addTimer:t forMode: NSDefaultRunLoopMode]; [t release];
NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(onTick:)]; NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn]; [inv setTarget: self]; [inv setSelector:@selector(onTick:)]; NSTimer *t = [NSTimer timerWithTimeInterval: 1.0 invocation:inv repeats:YES]; and after that, you start the timer manually whenever you need like this: NSRunLoop *runner = [NSRunLoop currentRunLoop]; [runner addTimer: t forMode: NSDefaultRunLoopMode]; And as a note, onTick: method looks like this: -(void)onTick:(NSTimer *)timer { //do smth }
NSTimer *timer; timer = [NSTimer scheduledTimerWithTimeInterval: 0.5 target: self selector: @selector(handleTimer:) userInfo: nil repeats: YES];
timerNoTwo = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(updateTimerNoTwo:) userInfo:nil repeats:YES]; - (void) updateTimerNoTwo:(NSTimer *) timer { [timerTwoOutputLabel setIntValue: [timerTwoOutputLabel intValue]+1]; }
//I am creating a dictionary object that I can pass to my selector method. NSArray *keys = [NSArray arrayWithObjects:@"key1", @"key2", @"key3", nil]; NSArray *objects = [NSArray arrayWithObjects:@"value1", @"value2", @"value3", nil]; NSDictionary *myDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fireTimer:) userInfo:myDictionary repeats:YES]; //The fireTimer() is the selector method I setup above - (void) fireTimer:(NSTimer*)theTimer { for (id key in [theTimer userInfo]) { NSLog(@"key: %@, value: %@", key, [[theTimer userInfo] objectForKey:key]); } //kill the timer [theTimer invalidate]; theTimer = nil; } /************************************************/ //here is a similar example but with using an NSNumber NSNumber *myInt = [NSNumber numberWithInt:4]; [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fireTimer:) userInfo:myInt repeats:YES]; - (void) fireTimer:(NSTimer*)theTimer { NSLog(@" %i ", [[theTimer userInfo] integerValue]); [theTimer invalidate]; theTimer = nil; }
@interface className { NSTimer * timer; } @property (nonatomic, retain) NSTimer * timer; @end @implementation className @synthesize timer; ... -(void) applicationDidFinishLaunching : (UIApplication *) application { timer = [NSTimer scheduledTimerWithInterval: 1.0 target:self selector:@selector(targetMethod:) userInfo:nil repeats: YES]; } //define the targetmethod -(void) targetMethod: NSTimer * theTimer { NSLog(@\"Me is here at 1 minute delay\"); } .. @end
NSTimer *mainTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerController) userInfo:nil repeats:YES]; - (void)timerController { seconds++; [[self timeLabel] setText:[self getTimeStr]]; } - (NSString*)getTimeStr : (int) secondsElapsed { int seconds = secondsElapsed % 60; int minutes = secondsElapsed / 60; return [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];