I am trying to schedule a GNUStep Objective-C method call to run every second for a variable number of seconds. I am trying to use NSTimer to schedule the method call, but the handler method never gets called.
Here is my code:
Timer.m
:
- (id) init {
self = [super init];
if(self) {
_ticks = 0;
}
return self;
}
- (void) startWithTicks: (unsigned int) ticks {
_ticks = ticks; //_ticks is an unsigned int instance variable
if(_ticks > 0) {
[NSTimer scheduledTimerWithTimeInterval: 1.0
target: self
selector: @selector(onTick:)
userInfo: nil
repeats: YES];
}
}
- (void) onTick: (NSTimer*) timer {
NSLog(@"tick");
_ticks--;
if(_ticks == 0) {
[timer invalidate];
timer = nil;
}
}
main.m
:
int main(int argc, const char* argv[]) {
Timer* t = [[Timer alloc] init];
NSLog(@"Setting timer");
[t startWithTicks: 3];
usleep(5000);
NSLog(@"End of timer");
return 0;
}
I would expect the output to be
Setting timer
tick
tick
tick
End of timer
However, the output is
Setting timer
End of timer
Why is this and how can I fix it?
The timer won't run while your thread is sleeping.
Your timer class code works fine if you're using it from a ViewController.
If instead you'd like to use it within the main method, you'll want to explicitly run the mainRunLoop. Try adjusting your main method to this:
int main(int argc, char * argv[]) {
Timer *timer = [[Timer alloc] init];
NSLog(@"Setting Timer");
[timer startWithTicks:3];
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
NSLog(@"End of Timer");
return 0;
}
to run the mainRunLoop running for 3 seconds, which should produce your desired output.
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html https://developer.apple.com/documentation/foundation/nsrunloop