2011-07-14 60 views
1

首先,我知道有一些关于此主题的其他StackOverflow问题,但我已经阅读了所有这些问题,我仍然对如何处理我的情况感到困惑。我可能在这里错过了一些显而易见的东西,如果你能帮助澄清一下,我们将非常感谢!重复NSTimer锁UI线程

我有一个应用程序,它在视图内为图像添加动画做了很多工作 - 主要包括一次以直线移动一个或多个图像的大量图像。我首先考虑的是让它们变得简单,一旦在整个移动过程中使用UIView animateWithDuration关闭动画。但是我发现这并没有给我很大的力量来拦截这个动作或者阻止它或者检查它到底在哪里,所以我放弃了这个动作。我的新方法是使用NSTimer,每秒发射20次,做增量运动。这种方式我也可以立即干预(几乎)立即改变动画或停止它或更新状态标签,基于它是多远,等等等等。

首先...有可能有更好的方法比这个。随意建议更好的东西!

虽然这是可以接受的,但现在我的问题是,当这些动画发生时,我无法点击UI上的任何其他控件。我没有得到任何回应。它不像它只是缓慢或延迟 - 点击从来没有通过。看来NSTimer处理完全锁定了用户界面 - 但仅仅来自新的交互。我在定时器处理方法中对UI做出的更改发生得很好,而且非常活泼。

从我读过的这个应该不会发生。不过,我也看到this question的评论说,如果定时器处理密集,然后它可能锁定UI线程。我没有看到我的处理在这里是密集的 - 当然没有资源请求,只是一些数据操纵和动画的一些对象 - 但我可能会掩盖它。

我在这里有什么选择?起初我想我可能会创建一个新线程来启动计时器。但我记得读过,UI更新必须在主线程上发生。为什么是这样?此外,这真的能解决问题吗?我只是问太多的设备来处理这个计时器以及UI交互?还有什么我失踪?

任何和所有的意见,将不胜感激。

编辑:

我刚刚发现我的UI阻塞问题的原因。我正在使用带有块的animateWithDuration,但没有设置选项。因此UIViewAnimationOptionAllowUserInteraction未设置。我改变它设置这个选项,我的用户界面现在很高兴地回应。

这就是说,我仍然会留下这个问题,针对我的整体方法提出具体建议。谢谢。

回答

0

我会考虑使用CADisplayLink。从文档:

CADisplayLink对象是一个计时器对象,它允许您的应用程序将其绘图与显示刷新率同步。

您的应用程序会创建一个新的显示链接,提供一个目标对象和一个在屏幕更新时调用的选择器。接下来,您的应用程序将显示链接添加到运行循环中。

一旦显示链接与运行循环相关联,当屏幕内容需要更新时,将调用目标上的选择器。目标可以读取显示链接的timestamp属性以检索显示前一帧的时间。例如,显示电影的应用程序可能会使用时间戳来计算下一个要显示的视频帧。执行自己的动画的应用程序可能会使用时间戳来确定显示的对象在即将到来的帧中的显示位置和方式。持续时间属性提供了帧之间的时间量。您可以在应用程序中使用此值来计算显示器的帧速率,下一帧将显示的大致时间,并调整绘制行为,以便及时准备下一帧以供显示。

您的应用程序可以通过将paused属性设置为YES来禁用通知。另外,如果您的应用程序无法在所提供的时间内提供帧,您可能需要选择较慢的帧速率。与跳过帧的应用程序相比,具有较慢但一致帧频的应用程序对用户来说会更平滑。您可以通过更改frameInterval属性来增加帧之间的时间(并降低明显的帧速率)。

当您的应用程序使用显示链接完成时,它应该调用invalidate从所有运行循环中将其删除,并将其从目标中解除关联。

CADisplayLink不应该被分类。

0

我并不完全确定在程序中如何处理所有内容,但您可能只想考虑让一个线程/定时器控制所有对象及其移动。实际上不需要为每个对象创建单独的线程/定时器,因为这很容易导致问题。

您可以使用包含有关其方向,速度,持续时间等信息的移动项目创建一个类,然后让控制线程/计时器计算并移动对象。然后,您可以介入一个主控制器对象,而不必处理许多其他对象。

+0

对不起,也许我误导了你。我只有一个计时器来控制所有的物体和它们的运动 - 这几乎是你描述的。我认为即使这可能不是最好的方法。无论如何,关于这与如何锁定UI的问题有关的任何想法? – user700774

+0

对不起,我的印象是你使用了多个定时器或线程。这几乎肯定会造成太多人在跑步的问题。很高兴你的问题得到解决:) – mjdth

0

我想你会发现,即使你优化了这个,基于定时器的动画这样的表现也不会很好。

你可能想问一下你认为你无法用CoreAnimation做的具体事情。如果你解决了这些问题,你最终会得到比试图推出自己的更好的结果。

+0

感谢您的反馈。我不太确定那将如何工作。例如,假设我已经让我的图像沿着一条线移动,并且在给定的点上我想确定它的位置。或者没有实际执行动画,找出它应该在哪里。或取消它。我如何使用简单的UIView animateWithDuration方法来做到这一点? – user700774