- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 CGlayers 进行绘图,如文档所述,这是在 Canvas 上渲染绘图的更有效方式。
我基本上是绘制到 CGlayers 中,然后使用 CGContextDrawLayerInRect 将图层绘制到图形上下文中
这是我的 drawRect 方法
- (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];
}
在我的 touches Moved 函数中,我创建了 UIBezeirPath 并将其转换为 CGPath。
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
self.currentPath = [[DrawingPath alloc] init];
if(m_eraseButtonClicked)
{
[self.currentPath setPathColor:[UIColor clearColor]];
}
else
{
[self.currentPath setPathColor:self.lineColor];
}
CGPathRef cgPath = self.currentPath.path.CGPath;
mutablePath = CGPathCreateMutableCopy(cgPath);
[m_undoArray addObject:self.currentPath];
[self setNeedsDisplay];
}
接触结束
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[m_parentUndoArray addObject:[NSArray arrayWithArray:m_undoArray]];
}
我遇到的问题如下
1) 我用时间分析器 CGContextDrawLayerInRect 进行了测试,在绘图时占用了 90% 的时间,所以我想知道我们如何减少这种方法所花费的时间并优化 drawRect 方法.
2) 如果我画了几条长线并开始连续撤消/重做,那么你也会看到 CGContextDrawLayerInRect 这需要很多时间。
3) 如果我删除一些绘制的线条并开始重复撤消/重做,更糟糕的是,我的应用程序崩溃并显示内存警告,我不知道删除有什么问题,它占用了这么多内存。
编辑:代码,更新以显示静态分析器指出它们是内存问题的地方
最佳答案
根据我自己的实验,iOS 有时会使用 GPU,有时会使用 CPU 来处理 CGContextDrawLayerInRect,这取决于被复制的层的大小(以及可能的其他因素)。当它使用 CPU 时,它会慢 20 倍。
唯一的解决方案是通过使用 setNeedsDisplayInRect 而不是 setNeedsDisplay 来减小更新区域的大小,并在 drawRect 代码中添加 CGContextClipToRect(context, rect)。
关于ios - CGlayer 绘图性能低下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22176467/
我是一名优秀的程序员,十分优秀!