Performance drawRect性能
我需要在iPad上画很多从50万到100万的多边形。经过实验,我只能得到1帧,如果那样的话。这只是一个例子,我的真实代码有一些大小不错的多边形 这里有几个问题: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
//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的引用
- 创建一个新类,比如说
,从UIView子类化,并添加以下代码:MyLargeView
drawRect:
调用,它只会绘制到rect
参数指定的区域,该参数将对应于我们在awakeFromNib
方法中配置的CATiledLayer的平铺大小(512×512)。这将扩展到1000000×1000000像素的画布
可供选择的选项是,特别是
3_Tiling
我不知道iOS历史记录的详细信息,因此在第一次发布问题时,这可能不是一个选项。然而,在处理路径性能问题时,我想调用CAShapeLayer作为一个简单的选项。“iOS核心动画:高级技术”(在谷歌图书上找到)说CAShapeLayer“使用硬件加速绘图”,我认为这意味着它是基于GPU的实现。同一本书在第6章中有一个很好的用法示例,可以归结为:
这在我的应用程序中产生了巨大的性能差异,用仪器来衡量。如果您的性能问题是基于路径的,请在尝试CAShapeLayer之前不要涉入OpenGL。我也遇到了同样的问题。在谷歌无休止的搜索之后,CAShapeLayer终于救了我!以下是您需要执行的详细步骤:
//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];
}