【问题标题】:What is the proper way to make it so core graphics does not lag?使核心图形不滞后的正确方法是什么?
【发布时间】:2011-10-02 21:55:24
【问题描述】:

我使用 UIBezierPath 进行手指绘画(我的应用程序)。我使用 path = [UIBezierPath bezier path]; 创建它.它在 iPad 上总是滞后(并且从 drawrect 中调用它并没有改变任何东西)。我已经为此工作了几个小时,但没有找到解决方案,只是滞后了。有人会这么好心来帮助我吗?另外,我正在使用 NSTimer 来调用该函数。这是我的应用程序的旧方式,所以请帮我解决这个问题!!!!!!

【问题讨论】:

  • 您需要发布有关您的代码的更多详细信息,以使问题足够完整,任何人都可以提供帮助。例如,您是否正在调用 setNeedsDisplay?多久一次?
  • 是的,我每 0.05 秒调用一次(我尝试了 1 秒,只要计时器达到那一秒,它就会滞后)
  • -1 因为您在过去一天中(基本上)问了 4 次相同的问题。有 7 个人竭尽全力帮助您,而您却无视他们的建议,继续发布同样格式不正确的问题。
  • 我已经按照建议重建了我的项目三次(我花了 7 个小时将所有代码放入 setNeedsDisplay。我还尝试过线程和使用位图上下文。它对我不起作用。)我不应该再次发布问题,对此我深表歉意。我工作的公司给了我一个截止日期,即几天后,我希望在截止日期前完成这个应用程序。对不起
  • 好的。根据我在这个问题/cmets 中读到的内容,有一些可能需要改进的领域(见下文)。当您没有很好地详细说明您的问题时,我们很难提供帮助(提供准确的建议)。 hotpaw2 和我在你之前的问题中都回答了“渲染到位图”——你应该提到你试图解决这个问题的方法。

标签: iphone memory uikit core-graphics lag


【解决方案1】:

由于您的问题本身没有包含足够的详细信息,因此我将做一些不当的事情并将元答案发布到yourcurrentlastfivequestions

首先,drawRect: 上画图。

这很重要,我要再说一遍。

drawRect: 中画图,别无他法。

不是touchesMoved:withEvent:

不是touchesBegan:Ended:

drawRect:,别无他处。

如果您正在制作图像以保存到文件,那是一回事。但是,当您在屏幕上绘图时,除了drawRect:,您不会在其他任何地方这样做。

说真的。这很重要。

第 2 步:不要试图在其他时间强制进行绘制。

drawRect: 会在您绘画时为您调用。根据定义,在任何其他时间,你都不需要画画,所以画画就是在做你不需要做的事情。通过扩展,不要自己打电话给drawRect:。你不需要,它永远不会有帮助。

实际上,这只是第 1 步的扩展。如果您调用 drawRect:,则与您调用绘图代码时没有什么不同。绘图代码没有在任何地方重复,这很好,但它仍然在错误的时间运行。 drawRect:只在系统调用时才被调用。

setNeedsDisplay 的存在是为了告诉系统该绘图了。您应该在并且在您需要绘制的某些内容发生变化时这样做。您的视图的属性,模型中的某些东西——每当您要绘制的内容发生变化时,请发送setNeedsDisplay。不要在其他任何时间这样做;你不需要。

关闭计时器。你不需要它。反正已经有一个计时器,将你限制在 60 fps。

Core Graphics 不会滞后。不,真的,它没有。缓慢或“滞后”是因为您尝试做的太多或做错了什么。

不要进行不必要的缓存。您所做的一切都不需要图像缓存。

“滞后”是因为您试图从touchesMoved:withEvent: 和/或touchesBegan:/Ended: 绘制或强制绘制。见上文。


这是你需要做的:

在您的 touchesBegan:/Moved:/Ended: 方法或其他适当的响应者方法中,更新您的状态。这将包括贝塞尔路径。 请勿绘制,其中包括请勿致电drawRect:或以其他方式尝试强制绘制。

在您更新了您的状态之后,并且只有在您更新了之后,才向您自己发送setNeedsDisplay

在您的drawRect: 方法中,并且在您的drawRect: 方法中,绘制路径、渐变等任何您认为合适的内容。

做这些事情,你的应用程序会很快。使用核心图形。没有延迟。


另外,一些重要的阅读:

【讨论】:

  • 这可能是我见过的最高答案:问题质量比。太棒了,彼得·霍西。
  • 很好的答案,这正是我所需要的!!谢谢!
  • 很好的答案,了解你不应该在其他任何地方画画非常重要:)
【解决方案2】:

当您的视图必须根据对用户事件的响应而重绘时,不要使用计时器定期重绘。

当您收到需要重绘视图部分的触摸时,请使用 setNeedsDisplaysetNeedsDisplayInRect: 使您的视图无效。

一个复杂的触摸绘图 iPad 应用程序可能需要很多实时渲染,尤其是在您过度绘制时。仅在需要时绘制。

另一种选择:分层工作

您的应用中可能没有撤消功能,因此实现起来应该很简单。定期将您的图像合成为单个视图。当调用 draw rect 时,您可以绘制更少的路径(1 个大图像 + 更少的路径)。在这种情况下,缓存的支持位图肯定会有所帮助。

同样,您的帖子中没有太多细节,而且您还没有告诉我们分析器向您显示的内容。

【讨论】:

  • 还有,重要的一点:查看分析器向您展示的内容。 不要只向我们展示(虽然,是的,当您到达关于SO的问题)。自己看一下,真的很难,然后从消除它向您显示的热点开始。
  • 谢谢彼得,在我再次发布这样的问题之前,我会这样做!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 2020-06-30
  • 2022-11-18
相关资源
最近更新 更多