Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance drawRect性能_Performance_Ios_Ipad_Drawrect - Fatal编程技术网

Performance drawRect性能

Performance drawRect性能,performance,ios,ipad,drawrect,Performance,Ios,Ipad,Drawrect,我需要在iPad上画很多从50万到100万的多边形。经过实验,我只能得到1帧,如果那样的话。这只是一个例子,我的真实代码有一些大小不错的多边形 这里有几个问题: 为什么我不把Quartz框架添加到我的项目中呢 如果许多多边形重复出现,我可以在视图中利用它们,还是它们太重 任何替代品,QTPaint都可以处理此问题,但会浸入gpu。有类似QT或ios的软件吗 Opengl可以提高这种类型的2d性能吗 示例drawrect: //X Y Array of boxes - (void)drawRec

我需要在iPad上画很多从50万到100万的多边形。经过实验,我只能得到1帧,如果那样的话。这只是一个例子,我的真实代码有一些大小不错的多边形

这里有几个问题:

  • 为什么我不把Quartz框架添加到我的项目中呢
  • 如果许多多边形重复出现,我可以在视图中利用它们,还是它们太重
  • 任何替代品,QTPaint都可以处理此问题,但会浸入gpu。有类似QT或ios的软件吗
  • Opengl可以提高这种类型的2d性能吗
  • 示例drawrect:

    //X Y Array of boxes
    
    - (void)drawRect:(CGRect)rect
    {
        int reset = [self pan].x;
        int markX = reset;
        int markY = [self pan].y;
        CGContextRef context = UIGraphicsGetCurrentContext();
        for(int i = 0; i < 1000; i++)//1,000,000
        {
            for(int j = 0; j < 1000; j++)
            {
                CGContextMoveToPoint(context, markX,  markY);
                CGContextAddLineToPoint(context, markX, markY + 10);
                CGContextAddLineToPoint(context, markX + 10, markY + 10);
                CGContextAddLineToPoint(context, markX + 10, markY);
                CGContextAddLineToPoint(context, markX, markY);
                CGContextStrokePath(context);
                markX+=12;
            }
            markY += 12;
            markX = reset;
        }
    
    }
    
    //X Y盒数组
    -(void)drawRect:(CGRect)rect
    {
    int reset=[self pan].x;
    int markX=重置;
    int-markY=[self-pan].y;
    CGContextRef context=UIGraphicsGetCurrentContext();
    对于(int i=0;i<1000;i++)//1000000
    {
    对于(int j=0;j<1000;j++)
    {
    CGContextMoveToPoint(上下文、markX、markY);
    CGContextAddLineToPoint(上下文,markX,markY+10);
    CGContextAddLineToPoint(上下文,markX+10,markY+10);
    CGContextAddLineToPoint(上下文,markX+10,markY);
    CGContextAddLineToPoint(上下文、标记x、标记y);
    CGContextStrokePath(上下文);
    markX+=12;
    }
    markY+=12;
    markX=重置;
    }
    }
    

    平移只是用平移手势在屏幕上移动框阵列。任何帮助或提示都将不胜感激。

    第4点。OpenGL应该可以做到这一点。检查是否可以重用这些对象,以及是否可以将一些逻辑移到GLSL代码中


    OpenGL性能优化(在WebGL环境下,但大部分都应适用):

    OpenGL是在iOS设备上加速的GPU硬件。核心图形绘制不是,并且在处理大量小型图形原语(线)时,速度可能慢很多倍


    对于许多小正方形,用C代码将它们写入位图比绘制核心图形线要快。完成后,只需将位图绘制到视图中一次。但是OpenGL会更快。

    您的示例的关键问题是它没有得到优化。无论何时调用
    drawRect:
    ,设备都会渲染所有1000000个正方形。更糟糕的是,它对循环中的API进行了6000000次调用。如果您想以每秒30帧的速度刷新此视图,即每秒180000000次呼叫

    使用“简单”示例,绘图区域的大小为12000px×12000px;iPad显示屏上可以显示的最大面积为768×1024(假设为全屏人像)。因此,代码在可见区域之外绘制会浪费大量CPU资源。UIKit可以相对轻松地处理这种情况

    管理明显大于可见区域的内容时,应将绘图限制为仅可见的内容。UIKit有两种处理方法;UIScrollView与CATILDELAYER支持的视图相结合是最佳选择

    步骤: 免责声明:这是对上述示例代码的优化

    • 创建新的基于视图的应用程序项目
    • 添加对QuartzCore.framework的引用
    • 创建一个新类,比如说
      MyLargeView
      ,从UIView子类化,并添加以下代码:
    :

    如果查看
    drawRect:
    调用,它只会绘制到
    rect
    参数指定的区域,该参数将对应于我们在
    awakeFromNib
    方法中配置的CATiledLayer的平铺大小(512×512)。这将扩展到1000000×1000000像素的画布


    可供选择的选项是,特别是
    3_Tiling

    我不知道iOS历史记录的详细信息,因此在第一次发布问题时,这可能不是一个选项。然而,在处理路径性能问题时,我想调用CAShapeLayer作为一个简单的选项。“iOS核心动画:高级技术”(在谷歌图书上找到)说CAShapeLayer“使用硬件加速绘图”,我认为这意味着它是基于GPU的实现。同一本书在第6章中有一个很好的用法示例,可以归结为:

  • 创建一个CAShapeLayer
  • 配置其线宽、填充颜色、笔划颜色等
  • 将该层添加为视图containerView.layer的子层
  • 要绘制路径,只需将其设置为图层的“路径”属性

  • 这在我的应用程序中产生了巨大的性能差异,用仪器来衡量。如果您的性能问题是基于路径的,请在尝试CAShapeLayer之前不要涉入OpenGL。

    我也遇到了同样的问题。在谷歌无休止的搜索之后,CAShapeLayer终于救了我!以下是您需要执行的详细步骤:

  • 通过重写UIView的+(类)layerClass方法,创建一个以CAShapeLayer作为图层类型的视图
  • 配置图层的线宽、fillColor、strokeColor等
  • 创建UIBezierPath实例
  • 要绘制路径,请使用UIBezierPath实例添加直线、曲线或acr等,完成绘制后,只需将bezierPath.CGPath设置为 图层的“路径”属性
  • 以下是一个简单的演示,用于在触摸演示视图时绘制简单曲线:

    //Simple ShapelayerView.m
    
    -(instancetype)init {
        self = [super init];
        if (self) {
        _bezierPath = [UIBezierPath bezierPath];
        CAShapeLayer *shapeLayer = (CAShapeLayer *)self.layer;
    
        shapeLayer.lineWidth = 5;
        shapeLayer.lineJoin = kCALineJoinRound;
        shapeLayer.lineCap = kCALineCapRound;
        shapeLayer.strokeColor = [UIColor yellowColor].CGColor;
        shapeLayer.fillColor = [UIColor blueColor].CGColor;
        }
    
        return self;
    }
    
    + (Class)layerClass {
        return [CAShapeLayer class];
    }
    
    - (void) customDrawShape {
        CAShapeLayer *shapeLayer = (CAShapeLayer *)self.layer;
        [_bezierPath removeAllPoints];
    
        [_bezierPath moveToPoint:CGPointMake(10, 10)];
        [_bezierPath addQuadCurveToPoint:CGPointMake(2, 2) controlPoint:CGPointMake(50, 50)];
    
        shapeLayer.path = _bezierPath.CGPath;
    }
    
    - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
        [super touchesBegan:touches withEvent:event];
        [self customDrawShape];
    }
    

    即使这篇文章已经很老了:我试过这篇文章,它似乎很有效。但是如果我在scrollview中有一个大的uitableview,其中的单元格中有很多UIView呢?我是否必须将单元格的绘图放在drawRect:函数中?谢谢
    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIScrollView *scrollView = [self.view.subviews objectAtIndex:0];
        scrollView.contentSize = CGSizeMake(12000, 12000);
    }
    
    //Simple ShapelayerView.m
    
    -(instancetype)init {
        self = [super init];
        if (self) {
        _bezierPath = [UIBezierPath bezierPath];
        CAShapeLayer *shapeLayer = (CAShapeLayer *)self.layer;
    
        shapeLayer.lineWidth = 5;
        shapeLayer.lineJoin = kCALineJoinRound;
        shapeLayer.lineCap = kCALineCapRound;
        shapeLayer.strokeColor = [UIColor yellowColor].CGColor;
        shapeLayer.fillColor = [UIColor blueColor].CGColor;
        }
    
        return self;
    }
    
    + (Class)layerClass {
        return [CAShapeLayer class];
    }
    
    - (void) customDrawShape {
        CAShapeLayer *shapeLayer = (CAShapeLayer *)self.layer;
        [_bezierPath removeAllPoints];
    
        [_bezierPath moveToPoint:CGPointMake(10, 10)];
        [_bezierPath addQuadCurveToPoint:CGPointMake(2, 2) controlPoint:CGPointMake(50, 50)];
    
        shapeLayer.path = _bezierPath.CGPath;
    }
    
    - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
        [super touchesBegan:touches withEvent:event];
        [self customDrawShape];
    }