渲染由设备频繁更新的行的最佳方法

时间:2016-09-19 23:58:19

标签: ios core-graphics uibezierpath cashapelayer cgpath

所以现在我有一个持续的数据流进入设备,我想在数据进入时实时绘制趋势线。

以下是我如何将测试数据输入系统

    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.100f
                                                  target:self
                                                selector:@selector(didGetTimerEvent:)
                                                userInfo:nil
                                                 repeats:YES];

    //
    // This is what's in the timer function
    //
    static CGFloat trigger = 0;
    const CGFloat weight = 50;

    // the line view, unsurprisingly, is what draws the line
    lineView.value = 12 * cosf(trigger) * M_PI * 0.6 + weight;
    trigger++;
    if (trigger > 100) trigger = 0;

简单吧,这只是一条波浪线。

在行视图的setValue属性中,它将值附加到NSArray。然后它调用一个渲染函数,在该函数中创建一个点并将其添加到CGPath,然后将其设置为CAShapeLayer的path属性。之后,CAShapeLayer会处理将所述点绘制到屏幕上的详细信息。

这是绘制经常更新此行的最佳方法吗?

如果我只在屏幕上放置一个图表,那么分析器中的CoreAnimation仪器会读取我以25 fps的速度绘图,所以现在我开始重新考虑我的实现。

2 个答案:

答案 0 :(得分:1)

这是一个相当标准的优化问题。首先,您需要确保有效地绘制线条。周围有很多东西:

  • 在您的CGContext中关闭您真正不想要的任何花哨选项(如果您使用的是CGPath,还有UIBezierPath上的其他选项,尤其要确保尽可能简单地设置setFlatnesssetLineCapsetLineJoin等内容。您甚至可能要关闭setShouldAntialias

  • 确保您没有添加短于某一点的线段。这是一个常见的错误。

  • 不要让路径无限制地增长。我在旧硬件(iPad 3)上使用大约5000个元素的路径运气不错,但如果让路径永远增长,任何硬件都会被淹没。

  • 最终您可能会发现在CGBitmapContext中自己绘制更改要容易得多。如果需要,您甚至可以直接翻转像素。通过这种方式很难获得漂亮的抗锯齿线,但你绝对可以超快。

  • 不要比屏幕刷新更快地更新曲线。这是另一个常见错误,当屏幕每秒更新60次时,人们每秒计算100次复杂曲线。

但大多数情况下这只是一个绘图优化问题。所有有趣的代码都在您未显示的setValue方法中。如果你在管理甚至30fps方面遇到了麻烦,那么是的,你肯定会对你的绘图进行剖析。

答案 1 :(得分:1)

我很惊讶它显示了25fps。您的计时器仅为1 / 10s,因此该行当前应仅以10fps更新。尝试更快地启动计时器,并考虑使用CADisplayLink - 它是以设备帧速率进行更新的更好方式。