Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 在iOS上运行无休止的循环动画_Iphone_Objective C_Ios_Cocoa Touch - Fatal编程技术网

Iphone 在iOS上运行无休止的循环动画

Iphone 在iOS上运行无休止的循环动画,iphone,objective-c,ios,cocoa-touch,Iphone,Objective C,Ios,Cocoa Touch,我有一个简单的UIView,它使用drawRect:绘制自身。为了使视图具有动画效果,需要每隔0.05秒调用drawRect方法,因此我使用了一个重复计时器: timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES]; 我不太了解运行循环、线程和所有系统的东西,所以我想知道这是否是运

我有一个简单的UIView,它使用
drawRect:
绘制自身。为了使视图具有动画效果,需要每隔0.05秒调用
drawRect
方法,因此我使用了一个重复计时器:

timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self 
        selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];

我不太了解运行循环、线程和所有系统的东西,所以我想知道这是否是运行动画的正确方法?这个计时器无休止地重复它自己。这是我应该担心的吗?这会阻塞主线程吗?如何将对性能的总体影响降至最低?

如果使用重写或自定义方法,则应使用递归和完成块来调用动画。我发现它比计时器工作得好得多,因为计时器并不总是精确的,如果你为自行车计时动画,它可能会导致一些动画问题


编辑:我不太了解如何使用drawRect:并调用[self-setNeedsDisplay]来更新它,所以在这方面我帮不了你。抱歉。

这种方法不错,但还有其他方法

计时器的目标方法必须将计时器作为参数,因此不应直接为setNeedsDisplay设置它,而应设置如下方法:

- (void)animationTimerDidFire:(NSTimer *)timer
{
    [myView setNeedsDisplay];
}
如果您的视图始终可见,那么您可以设置并忘记计时器。另一方面,如果由于切换到不同的视图,计时器可能会消失,则需要根据需要使计时器失效并重新创建计时器

应用程序的主线程使用运行循环并调用各种方法来响应事件,如用户点击、系统通知(例如内存警告)和I/O到达。如果运行循环调用的任何内容需要很长时间才能返回,它将占用队列中的所有内容。设置计时器时,它会被添加到列表中,并且运行循环每次都会对其进行检查;如果其中一个计时器准备就绪,它将调用您的方法

最终的结果是计时器并不精确:它们可能不会像你喜欢的那样频繁启动,可能会被延迟调用,等等。同样,如果你的应用程序非常简单,那么主运行循环不会非常繁忙,因此计时器可能就足够了。只需确保动画基于两次调用之间实际经过的时间,而不是假设每次调用正好间隔0.05秒

选择 如果动画只涉及翻转一些静态图像,UIImageView对此有一定的支持

如果创建动画的每一帧都需要相当长的时间(并且您不想阻止主线程),则可以使用背景队列绘制图像(请参见
CGBitmapContextCreate
CGBitmapContextCreateImage
),然后在新图像准备好显示时向主线程发送信号。任何涉及视图的操作都必须发生在主线程上,但您可以在背景上进行绘制

您可能还需要阅读QuartzCore框架中的
CALayer
。这就是UIView对象在屏幕上绘制的实际操作。您可能会发现,通过操纵某些CALayer对象并让核心动画执行繁重的操作(例如,将颜色从红色更改为蓝色,核心动画负责从一个渐变到另一个),而不是绘制,可以获得所需的效果