How to get NSTimer to loop

2019-08-22 04:44发布

问题:

I'm trying to learn about NSTimer, using Foundation and printing to the console. Can anybody tell me what I need to do to get the following to work? It compiles with no errors, but does not activate my startTimer method -- nothing prints.

My aim is to get one method to call another method to run some statements, and then stop after a set time.

#import <Foundation/Foundation.h>

@interface MyTime : NSObject {
    NSTimer *timer;
}
- (void)startTimer;
@end

@implementation MyTime

- (void)dealloc {
    [timer invalidate];
    [super dealloc];
}

- (void)startTimer {
     timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(runTimer:) userInfo:nil repeats:YES];
}

- (void)runTimer:(NSTimer *)aTimer {
    NSLog(@"timer fired");
}
@end


int main(int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


    MyTime *timerTest = [[MyTime alloc] init];
    [timerTest startTimer];

    [timerTest release];

    [pool release];
    return 0;
}

回答1:

The timer never gets a chance to fire in your program, because the program ends almost immediately after the timer is created.

There's a construct called the Run Loop which is responsible for processing input, including input from timers. One run loop is created for each thread, but it isn't automatically started in this case.

You need to run the run loop and keep it going until the timer has a chance to fire. Fortunately, this is quite easy. Insert:

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];

between sending startTimer and release to timerTest. If you want the timer to repeat, you'll need to continue keeping the run loop active.

Note that you only need to do that in a simple program like this; when you are creating an application with a GUI, the run loop will be started via the Cocoa application setup process, and will remain active until the application terminates.



回答2:

You have to add your timer to the default runloop after initializing it:

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

Put this in -(void)startTimer.