这种方法还不错,但还有其他方法可以做到。
计时器的目标方法必须将计时器作为参数,因此不要直接将其设置为 setNeedsDisplay,而应设置如下方法:
- (void)animationTimerDidFire:(NSTimer *)timer
{
[myView setNeedsDisplay];
}
如果您的视图始终可见,那么您可以设置并忘记计时器。另一方面,如果它可能因为您切换到不同的视图而消失,您将需要根据需要使计时器无效并重新创建。
应用程序的主线程使用运行循环并调用各种方法来响应事件,例如用户点击、系统通知(例如内存警告)和 I/O 到达。如果运行循环调用的任何东西需要很长时间才能返回,它会阻止队列中的所有内容。当您设置一个计时器时,它会被添加到一个列表中,并且运行循环每次都会检查它;如果其中一个计时器准备就绪,它会调用您的方法。
最终的结果是计时器并不精确:它们可能不会像你喜欢的那样频繁地触发,可能会被延迟调用等等。同样,如果你的应用程序非常简单,主运行循环不会很忙,所以一个计时器可能会足够好。只要确保你的动画是基于调用之间的实际时间,而不是假设每个调用恰好相隔 0.05 秒。
备择方案
如果您的动画仅涉及翻转一些静态图像,则 UIImageView 对此提供了一些支持。
如果创建每一帧动画需要大量时间(并且您不想阻塞主线程),您可以使用后台队列来绘制图像(参见CGBitmapContextCreate
和CGBitmapContextCreateImage
),然后在新的时候向主线程发出信号图像已准备好显示。任何触及视图的事情都必须发生在主线程上,但您可以在背景上进行绘图。
您可能还想阅读CALayer
QuartzCore 框架。这是 UIView 对象实际操作以在屏幕上绘制的内容。您可能会发现,您可以通过操作一些 CALayer 对象并让 Core Animation 完成繁重的工作(例如,您将颜色从红色更改为蓝色,Core Animation 负责从一到另一个)。