Mac OS X is a very dynamic operating system. At any given time the computer may be working on several tasks at once. Your application has to be a good citizen in this environment and should not tie up the CPU any more than it has to. If you want to perform some animation in your application, you might do so by providing a loop that draws a frame, pauses for some time interval, and then draws another frame. Unfortunately, your application will be completely occupied while in this loop and might make better use of its time by performing some other calculations in the time that it has paused to render the next frame. Moreover, if the user tries to interact with your program during that pause, and the program is unable to respond, they might perceive your application as unresponsive and sluggish. To work around this problem, Mac OS X includes many different systems that provide timers.
About TimersA timer is little more than an entity on the system that calls back to your application at a fixed interval. Your application can set up a timer to call you back at the frame rate of your animation. When you receive the notification that the timer has fired, your application can draw one frame of the animation (or indicate to a view that the next frame needs to be drawn) and return. In the mean time, however, your application can continue to process user events or perform some important calculation. It only needs to worry about managing the animation when that animation needs attention. One of the hardest parts about using timers is deciding which timing mechanism to use. At the lowest levels of the application frameworks, you have run loop timers, CFRunLoopTimer. Each of the application frameworks also offer timer objects. Carbon application can use Carbon event timers, and Cocoa applications can use NSTimer objects. The actual choice you make depends largely on what type of notification mechanism you prefer. CFRunLoopTimers notifies your application when the timer fires by invoking a callback routine. Carbon event timers, naturally, send a Carbon event when the timer fires. NSTimer objects can invoke a method on an Objective-C object when their timer expires. As a general rule of thumb, you will probably be best off if you use the timing mechanism that matches your application architecture. Just keep in mind that the other timing mechanisms are also there to help you if you need them.
Updating the AnimationThe way you draw the frames of the animation is another important consideration on Mac OS X. The simplest way to respond to a timer asking you to draw the next frame of your animation might be to simply draw the frame and return control. However, on Mac OS X, the Carbon and Cocoa application frameworks like to take a more structured approach to drawing. In Carbon, your application usually draws its user interface in response to a kEventControlDraw message sent to a particular HIView. In Cocoa, an application draws an NSView in response to the drawRect: message. As a rule of thumb, in both frameworks, your application shouldn't be drawing outside of these two mechanisms unless it has very special drawing behavior (e.g., if has captured the screen and is drawing in full-screen mode). To work with the operating system, your application should draw the frames of the transition animation within the appropriate context. All that your timer callback needs to do is induce the operating system to call your view's draw handler. To do that the timer callback mechanism might call HIViewSetNeedsDisplay for a Carbon application or one of the NSView methods that begin with setNeedsDisplay: in Cocoa. Animation Speed and Refresh RatesWhen you watch TV or view a movie, the screen is showing you the individual frames of the picture at a rate that is probably in the range of 24 to 36 frames per second. To prevent flickering as it updates the screen, Mac OS X tries to synchronize the flushing of windows to the refresh rate of the monitor. In contrast, the LCD displays on many Macintosh computers typically refresh their images at a rate of 60 frames per second, while CRT monitors might refresh a little more frequently. What this means in terms of animation is that if your application is trying to draw an animation, like a Core Image transition, at a rate faster than 60 frames per second, you are not using your time effectively and the user is not likely to see all the frames you are drawing anyway. When you are trying to decide on an animation rate for your transition, unless your application has very special needs, you might start with 30 frames per second and test the transition. Use higher refresh rates if you must, but keep in mind that there is an upper limit on the number of images the user will see. |