I am running a mainLoop in Cocoa using an NSTimer set up like this:
mainLoopTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/fps target:self selector:@selector(mainloop) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:mainLoopTimer forMode:NSEventTrackingRunLoopMode];
At Program startup I set the timeInterval to 0.0 so that the mainloop runs as fast as possible. Anyways, I would like to provide a function to set the framerate(and thus the time interval of the timer) to a specific value at runtime. Unfortunately as far as I know that means that I have to reinitialize the timer since Cocoa does not provide a function like "setTimerInterval" This is what I tried:
- (void)setFrameRate:(float)aFps
{
NSLog(@"setFrameRate");
[mainLoopTimer invalidate];
mainLoopTimer = nil;
mainLoopTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/aFps target:self selector:@selector(mainloop) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:mainLoopTimer forMode:NSEventTrackingRunLoopMode];
}
but this throws the following error and stops the mainloop:
2010-06-09 11:14:15.868 myTarget[7313:a0f] setFrameRate 2010-06-09 11:14:15.868 myTarget[7313:a0f] * __NSAutoreleaseNoPool(): Object 0x40cd80 of class __NSCFDate autoreleased with no pool in place - just leaking 2010-06-09 11:14:15.869 myTarget[7313:a0f] * __NSAutoreleaseNoPool(): Object 0x40e700 of class NSCFTimer autoreleased with no pool in place - just leaking 0.614628
I also tried to recreate the timer using the "retain" keyword, but that didn't change anything. Any ideas about how to dynamically change the interval of an NSTimer at runtime?
Thanks!
I know, this thread is amazing old! But I was in search of the functionality too!
As it turned out, that the NSTimes doesn't provide this feature, I decided to build an own one. It's not the best solution, but in my case it was the only possible.
I defined the variable "BOOL keepOn;" in my header.
-(IBAction)doSomething:(id)sender
{
// Any action to throw every interval.
}
-(IBAction)switchAutoLoad:(id)sender
{
if([autoLoad state] == NSOffState)
{
NSLog(@"auto-reload on!");
self performSelector:@selector(fireTimer) withObject:nil afterDelay:0];
keepOn = YES;
[autoLoad setState:NSOnState];
}
else
{
NSLog(@"auto-reload off!");
keepOn = NO;
[autoLoad setState:NSOffState];
}
}
-(void)fireTimer
{
[self doSomething:nil];
float theTime = 20; // This is the time interval.
if(keepOn)
{
[self performSelector:@selector(fireTimer) withObject:nil afterDelay:theTime];
}
}
The (very) bis issue is, that the "timer" is waiting the whole delay, before it can get a new value. You see, it's not responding fast :)) And you can't stop it immediately (have to wait for the delay to finish).
And if you stop it, it's throwing one more action as supposed.
Actually it works for my and is ok for little apps and tools.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With