I tend to use a CADisplayLink to trigger new frames and a simple time calculation within the frame request to figure out how far to advance my logic.
Suppose you have a member variable, timeOfLastDraw, of type NSTimeInterval. You want your logic to tick at, say, 60 beats per second. Then (with a whole bunch of variables to make the code more clear):
- (void)displayLinkDidTick
{
// get the time now
NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate];
// work out how many quantums (rounded down to the nearest integer) of
// time have elapsed since last we drew
NSTimeInterval timeSinceLastDraw = timeNow - timeOfLastDraw;
NSTimeInterval desiredBeatsPerSecond = 60.0;
NSTimeInterval desiredTimeInterval = 1.0 / desiredBeatsPerSecond;
NSUInteger numberOfTicks = (NSUInteger)(timeSinceLastDraw / desiredTimeInterval);
if(numberOfTicks > 8)
{
// if we're more than 8 ticks behind then just do 8 and catch up
// instantly to the correct time
numberOfTicks = 8;
timeOfLastDraw = timeNow;
}
else
{
// otherwise, advance timeOfLastDraw according to the number of quantums
// we're about to apply. Don't update it all the way to now, or we'll lose
// part quantums
timeOfLastDraw += numberOfTicks * desiredTimeInterval;
}
// do the number of updates
while(numberOfTicks--)
[self updateLogic];
// and draw
[self draw];
}
In your case, updateLogic would apply a fixed amount of rotation. If constant rotation is really all you want then you could just multiply the rotation constant by numberOfTicks, or even skip this whole approach and do something like:
glRotatef([NSDate timeIntervalSinceReferenceData] * rotationsPerSecond, 0, 0, 1);
instead of keeping your own variable. In anything but the most trivial case though, you usually want to do a whole bunch of complicated things per time quantum.