CALayer 的 border、圆角、阴影、遮罩(mask),CASharpLayer 的矢量图形显示,通常会触发离屏渲染(offscreen rendering),而离屏渲染通常发生在 GPU 中。当一个列表视图中出现大量圆角的 CALayer,并且快速滑动时,可以观察到 GPU 资源已经占满,而 CPU 资源消耗很少。这时界面仍然能正常滑动,但平均帧数会降到很低。为了避免这种情况,可以尝试开启 CALayer.shouldRasterize 属性,但这会把原本离屏渲染的操作转嫁到 CPU 上去。对于只需要圆角的某些场合,也可以用一张已经绘制好的圆角图片覆盖到原本视图上面来模拟相同的视觉效果。最彻底的解决办法,就是把需要显示的图形在后台线程绘制为图片,避免使用圆角、阴影、遮罩等属性。
- (UIImage *)drawCornerInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius {
UIImage * image = nil;
// 创建贝塞尔曲线对象
UIBezierPath * bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];
// 开始设置绘图
UIGraphicsBeginImageContextWithOptions(rect.size, false, [UIScreen mainScreen].scale);
CGContextAddPath(UIGraphicsGetCurrentContext(), bezierPath.CGPath);
CGContextClip(UIGraphicsGetCurrentContext());
// 调用绘制方法
[self drawInRect:rect];
// 绘制图片
CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
// 获取绘制完成的image
image = UIGraphicsGetImageFromCurrentImageContext();
// 结束绘制
UIGraphicsEndImageContext();
return image;
}