tags:

views:

279

answers:

2

Hi,

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!

+1  A: 
garph0
what should I do instead to change the interval?
I beg your pardon. I misread [mainLoopTimer release].You are acting correctly with the timer, but it seems to be no AutoReleasePool in place. have a look here: http://developer.apple.com/mac/library/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html
garph0
hmm I allready tried to put an autoreleasepool in place, but it didn't work, but I will try again!
okay, if I put an autoreleasepool in place, and init the timer like this:mainLoopTimer = [[NSTimer scheduledTimerWithTimeInterval:fps target:self selector:@selector(mainloop) userInfo:nil repeats:YES] autorelease]; it does not throw the leaking error, but the App gets interrupted. Any other ideas?
Do you get any error?
garph0
no, just GDB: Interrupted, I am pretty sure the problem is that I overWrite timer. isn't there any other way to set the interval?
Nope. Here is another question on the subject here on SO: http://stackoverflow.com/questions/1582740/restart-nstimer-firing-interval . There must be some other problem. I have no mac here, so I cannot make any test
garph0
Well I replaced the Timer with an performSelector call on the mainloop itself and now everything works, eccept that performSelector seems to be inaccurate since it does not reach the FPS I tell it to, and always is a few FPS slower (ie instead of 60 only 57 or instead of 120 only 114), any ideas?
A: 

You can try un-register previous timer and start new one with different frequency. you can un-register by

[yourOldTimer invalidate];
yourOldTimer = nil;

This might solve the purpose.

Unicorn
as you can see, thats what I did allready, and it does not work.