Graphics Reference
In-Depth Information
self .timer = nil ;
}
}
@end
That works pretty well, and is roughly the same amount of code as the keyframe-based
version. But there are some problems with this approach that would become apparent if we
tried to animate a lot of things onscreen at once.
An NSTimer is not the optimal way to draw stuff to the screen that needs to refresh every
frame. To understand why, we need to look at exactly how NSTimer works. Every thread on
iOS maintains an NSRunloop , which in simple terms is a loop that endlessly works through
a list of tasks it needs to perform. For the main thread, these tasks might include the
following:
Processing touch events
Sending and receiving network packets
Executing code scheduled using GCD (Grand Central Dispatch)
Handling timer actions
Redrawing the screen
When you set up an NSTimer , it gets inserted into this task list with an instruction that it
must not be executed until at least the specified time has elapsed. There is no upper limit on
how long a timer may wait before it fires; it will only happen after the previous task in the
list has finished. This will usually be within a few milliseconds of the scheduled time, but it
might take longer if the previous task is slow to complete.
The screen redrawing is scheduled to happen every sixtieth of a second, but just like a timer
action, it may get delayed by an earlier task in the list that takes too long to execute.
Because these delays are effectively random, the result is that it is impossible to guarantee
that a timer scheduled to fire every sixtieth of a second will always fire before the screen is
redrawn. Sometimes it will happen too late, resulting in a delay in the update that will make
the animation appear choppy. Sometimes it may fire twice between screen updates,
resulting in a skipped frame that will make the animation appear to jump forward.
We can do some things to improve this:
We can use a special type of timer called CADisplayLink that is designed to fire in
lockstep with the screen refresh.
We can base our animations on the actual recorded frame duration instead of
assuming that frames will fire on time.
Search WWH ::




Custom Search