【问题标题】:Core graphics using too much CPU使用过多 CPU 的核心图形
【发布时间】:2014-02-19 17:38:23
【问题描述】:

我正在实现以下图形 drawRect 函数,但它使用超过 50% 的 CPU - 知道如何解决这个问题吗?我只是随便画了几条线,但我希望它们都有不同的宽度。

- (void)drawRect:(CGRect)rect
{

    [super drawRect:rect];

    @autoreleasepool {

        CGContextRef context = UIGraphicsGetCurrentContext();
        CGMutablePathRef path = CGPathCreateMutable();



        float width = rect.size.width;
        int nbLine=10; // i want to draw 10 paths

        for (int iLine=1;iLine<nbLine;iLine++){

            float Pathwidth=0.8*(nbLine-(float)iLine)/nbLine;
            CGContextBeginPath(context);
            CGContextSetLineWidth(context, Pathwidth); //each path should have its own width
            CGPathMoveToPoint(path, NULL, 0,0);

            for (int i=0;i<10;i++){
                float x=width/(i+1);
                float y=1;//for this example, I just put a fixed number here - it's normally an external variable
                CGPathAddQuadCurveToPoint(path, NULL, x+width/10, y,  x,0);


            }

            CGContextAddPath(context, path);
            CGContextStrokePath(context);
        }

        CGPathRelease(path);

    }
}

谢谢!

【问题讨论】:

  • 绘图应该最大化 CPU。绘制需要多长时间?
  • 你有@autoreleasepool是有原因的吗?
  • @autoreleasepool 没有理由(只是一个测试)。它的绘制速度非常快,并且每个周期都会正确更新(我相信每 4 毫秒)
  • 周期有什么变化?为什么要重绘每一帧?
  • 因为在每个循环中,float y=1 实际上都会更新一个新值(我已经为示例进行了简化)

标签: ios core-graphics core-animation


【解决方案1】:

您可以尝试一些事情。

  1. 使用仪器准确找出哪些线路正在使用 CPU。
  2. 在 UIBezierPath 中构建一次路径,然后每次在 drawRect 中绘制它们。
  3. 查看从哪里调用 setNeedsDisplay。很可能每次绘制它都不会占用太多 CPU。问题很可能是它一遍又一遍地快速绘制。

【讨论】:

  • - 每条路径都是不同的(实际上只是其他路径的相似性)。然后 setNeedsDisplay 是这样调用的: - (void)startDisplayLink { _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)]; [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; } - (void)handleDisplayLink:(CADisplayLink *)displayLink { [self setNeedsDisplayInRect:self.bounds]; }
【解决方案2】:

如果您需要性能,您可以使用 GLKView。核心绘图基于 OpenGL,为图形清晰度和质量设置了一大堆优化。但是,如果这些选项让您慢到无法使用的地步,那么这可能是您最好的选择。

我的第二个建议是不要经常抽签。您说它每 4 毫秒调用一次,即每秒 250 次。用户看不到那么精细的细节,太奢侈了。

我的第三个建议是使用 UIView,绘制一次,然后根据您的 y 变量修改它的变换。看起来好像你可以做一个简单的 y 缩放来实现你想要做的事情(没有 x 变化,没有线条宽度变化(在绘制一次之后))。根据您的代码,我可能会过度简化,但这将是一件好事。如果 y 比例变换变得太大,您也可以将此建议与您的代码混合使用并重绘。

【讨论】:

  • 我的错误,它被设置为每 40 毫秒而不是 4 毫秒,并且仍然会占用 CPU...我更担心应用程序会耗尽电池...我会尝试 UIView 技巧- 然而,似乎消耗最多 CPU 的是每个补丁必须具有不同的宽度......
猜你喜欢
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
  • 2020-04-07
  • 2016-02-27
相关资源
最近更新 更多