有没有一种方法可以强制Core Animation运行它的线程?

5
核心动画使用后台线程来完成其工作。现在问题是:我在主线程中有一个繁重的计算。核心动画立即冻结,直到该计算完成。然后它继续完成其动画。我记得在一份文档中读到,CA在处理时间上具有低优先级,这意味着无论主线程想要做什么都是高优先级,并且比同时进行的任何花哨的动画更有可能完成。
我希望强制Core Animation在任何情况下都能很好地安排其后台线程与主线程。或者使用一个单独的线程,在主线程外运行繁重的计算。我已经尝试过了,但是CA仍然会冻结,直到计算完成。我期望调度程序可以快速在CA和该计算之间切换处理时间。
如何强制CA继续工作?如果事情进行得比较慢,那没关系。但最重要的是,从用户的角度来看,所有事情都要继续进行。
3个回答

8

如果您不想让运行循环自然完成,可以使用[CATransaction flush]来刷新核心动画。


虽然这似乎只适用于iOS 4.0及以上版本。在此之前,它无法正确强制重绘,但也不会引起任何问题。 - monkeydom
我知道这已经过时了,但您介意详细说明一下[CATransaction flush]如何解决线程问题吗? - Warpling

5
不要在主线程上运行繁重的计算,因为它们会阻塞UI并导致不良用户体验。请在后台线程中运行它们。
话虽如此,iPhone是单核系统,因此如果一个计算占用了一个线程中的CPU,那么每个其他线程的性能可能会几乎停滞。如果可以,请尝试将计算分成较小的元素,并将它们作为NSOperations在NSOperationQueue中运行。如果确保计算段不太小,以至于为它们创建NSOperation的开销变得过大,这可能提供了一种限制计算速度的手段,以便您的动画不会被减慢。
核心动画往往会在动画运行之前执行大量计算,因此这些计算可能会受到您繁重的计算线程的影响。您还可以在CAAnimation的-animationDidStart:委托方法中启动您的繁重计算,使计算仅在动画进行时启动。我相信动画的进度使用的计算比其开始少,因此它可能更能与您的繁重计算共存。

谢谢。NSOperations能够设置超时吗?我的计算已经被拆分成了多个部分,每个部分都以0.05秒的延迟进行调度,所以实际上它们之间有一些空闲时间。但是,当CA在开始时需要进行预计算时,等待-animationDidStart的想法非常好。我尝试通过延迟第一个计算块的调用1秒来实现这一点。CA开始动画运行,然后进行繁重的计算,最终导致CA卡住。我正在新线程中运行计算。 - HelloMoon
重点是,在计算每个数据块之后,UI会发生更新。这些更新快速而顺畅,正如预期的那样。如果有一种方法可以安排所有这些工作,使CA与此共享CPU时间,那就太完美了...我将看看这些NSOperationQueue的东西,尽管它们听起来似乎不会像延迟performSelector调用那样提供超时(?) - HelloMoon
NSOperationQueue 根据需要为您的 NSOperations 创建线程。它在管理何时执行任务方面相当智能,但我不知道它在 iPhone 上是否具有与 Snow Leopard 上相同类型的系统级别意识(在那里它是在 GCD 之上叠加的)。它还支持任务之间的依赖关系,在这里您可能能够利用它们的优势。 - Brad Larson
听起来不错。你已经在iPhone上使用过它了吗?它会如何与核心动画交互?也许我得在这里摆脱CA,手动完成所有动画,以便可以强制平衡地共享CPU时间... - HelloMoon
即使你要实现自己的手动动画代码(这需要很长时间),你仍然会遇到同样的问题。如果你的繁重计算占用了太多处理器时间,导致核心动画出现卡顿,那么你认为你的手动动画不会有问题吗?我建议你花些时间使用Shark和Instruments来尝试先解决你的繁重计算问题。 - Brad Larson

-1

我不确定,但如果您在另一个线程中运行CA,可以尝试调用[NSThread setThreadPriority:1.0]


我在另一个线程中调用CA,这会有影响吗?据我所知,CA维护了自己的进程和线程来处理这种事情(或者至少是它自己的线程,并设置了非常低的优先级)。 - HelloMoon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接