Ios CGlayer绘图的性能较慢
我正在使用CGlayers进行绘图,正如文档所说,在画布上渲染绘图更有效 我基本上是绘制成CGlayers,然后使用CGContextDrawLayerRect 这是我的drawRect方法Ios CGlayer绘图的性能较慢,ios,core-graphics,cgcontext,cgpath,cglayer,Ios,Core Graphics,Cgcontext,Cgpath,Cglayer,我正在使用CGlayers进行绘图,正如文档所说,在画布上渲染绘图更有效 我基本上是绘制成CGlayers,然后使用CGContextDrawLayerRect 这是我的drawRect方法 - (void)drawRect:(CGRect)rect { switch (m_drawStep) { case DRAW: { CGContextRef context = UIGraphicsGe
- (void)drawRect:(CGRect)rect
{
switch (m_drawStep)
{
case DRAW:
{
CGContextRef context = UIGraphicsGetCurrentContext();//Get a reference to current context(The context to draw)
if(self.currentDrawingLayer == nil)//Potential leak of memory- static analyzer
{
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
self.currentDrawingLayer = layer;
}
CGContextRef layerContext = CGLayerGetContext(self.currentDrawingLayer);//Potential leak of memory- static analyzer
CGContextBeginPath(layerContext);
CGContextAddPath(layerContext, mutablePath);
CGContextSetLineWidth(layerContext, self.lineWidth);
CGContextSetStrokeColorWithColor(layerContext, self.lineColor.CGColor);
CGContextSetFillColorWithColor(layerContext, self.lineColor.CGColor);
CGContextSetBlendMode(layerContext,kCGBlendModeNormal);
CGContextStrokePath(layerContext);
CGPathRelease(mutablePath);
CGContextDrawLayerInRect(context, self.bounds, self.currentDrawingLayer );//Potential leak of memory- static analyzer
}
break;
case UNDO:
{
CGContextRef context = UIGraphicsGetCurrentContext();
if(self.currentDrawingLayer == nil)//Potential leak of memory- static analyzer
{
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
self.currentDrawingLayer = layer;
}
CGContextRef layerContext1 = CGLayerGetContext(self.currentDrawingLayer );//Potential leak of memory- static analyzer
CGContextClearRect(layerContext1, self.bounds);
for(NSArray *undoArray in m_parentUndoArray)
{
for(int i =0; i<[undoArray count];i++)
{
DrawingPath *drawPath = [undoArray objectAtIndex:i];
CGPathRef path = drawPath.path.CGPath;
mutablePath = CGPathCreateMutableCopy(path);
CGContextBeginPath(layerContext1);
CGContextAddPath(layerContext1, mutablePath);
CGContextSetLineWidth(layerContext1, drawPath.pathWidth.floatValue);
CGContextSetStrokeColorWithColor(layerContext1, drawPath.pathColor.CGColor);
if([drawPath.pathColor isEqual:[UIColor clearColor]])
{
CGContextSetBlendMode(layerContext1,kCGBlendModeClear);
}
else
{
CGContextSetBlendMode(layerContext1,kCGBlendModeNormal);
}
CGContextStrokePath(layerContext1);
CGPathRelease(mutablePath);
}
}
CGContextDrawLayerInRect(context, self.bounds, self.currentDrawingLayer);//Potential leak of memory- static analyzer
}
}
break;
[super drawRect:rect];
}
最后结束
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[m_parentUndoArray addObject:[NSArray arrayWithArray:m_undoArray]];
}
我面临的问题如下
1) 我使用时间探查器进行了测试,cgContextDrawLayerRect,在绘图时占用了90%的时间,因此我想知道如何减少此方法所占用的时间并优化drawRect方法
2) 如果我画了几行长的线,然后开始不断地执行撤消/重做,那么您也可以看到cgContextDrawLayerRect,这需要很多时间
3) 如果我删除一些绘制的线条,并开始重复执行撤消/重做,更糟糕的是,我的应用程序崩溃,内存警告,我不知道擦除出了什么问题,它占用了这么多内存
编辑:代码,已更新以显示静态分析器所说的内存问题。根据我自己的实验,似乎iOS有时会使用GPU,有时会使用CPU进行CGContextDrawLayerRect,具体取决于被复制层的大小(以及潜在的其他因素)。当它使用CPU时,速度要慢20倍
唯一的解决方案是通过使用setNeedsDisplayInRect而不是setNeedsDisplay,并在drawRect代码中添加CgContextCliptRect(context,rect)来减小更新区域的大小。Instruments是否使用leaks instrument报告内存泄漏?您是否启用了僵尸(这会导致释放的内存从未真正释放)?您是否在代码的Xcode中运行了静态分析器,以查看它是否报告内存管理问题?Hello@Gavin,它报告CoreGraphics函数的内存泄漏,我不知道僵尸,我没有运行任何静态分析器我运行了静态分析器,它报告的问题在上面的代码行中,我已经更新了。Hello@Gavin,关于这件事,你要说什么
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[m_parentUndoArray addObject:[NSArray arrayWithArray:m_undoArray]];
}