- [CALayer setNeedsDisplayInRect:]导致重绘整个图层

时间:2012-03-21 16:58:42

标签: ios cocoa-touch core-graphics calayer

我正在继承CALayer以提供我自己的方法绘图。为了优化,我致电-[MyLayer setNeedsDisplayInRect:]而不是-[MyLayer setNeedsDisplay]。在绘图方法中,我得到了应该通过CGContextGetClipBoundingBox()重新绘制的矩形。

如果我将此图层用作UIView的 base 图层,则每个图层都按预期工作。一旦我将自定义图层用作其他CALayer的子图层,就会出现问题。比CGContextGetClipBoundingBox()总是返回该图层边界的矩形。

有什么想法吗?

[编辑]

似乎没有保证,CALayer的内容被缓存,只有脏部分被重绘。我做了一个小测试并存储了需要显示为单独属性的rect。结果是,只有这部分在屏幕上可见。

我现在将渲染到图像上下文并将该图像保存为缓存。在绘制方法中,我只显示缓存的图像。

1 个答案:

答案 0 :(得分:6)

不幸的是,Apple的文档存在冲突,因为-setNeedsDisplayInRect上的文档未指明该方法是否在实践中有效。根据我自己的经验,this technote可以直截了当地说明:

  

请注意,由于iPhone / iPod touch / iPad更新其屏幕的方式,如果您调用-setNeedsDisplayInRect:或-setNeedsDisplay:将重绘整个视图。

话虽如此,如果您认为由于冗余绘图而撞墙,可以考虑很多事情。

  • 如果是绘制图像,您可以进行的最大性能改进是使用与您绘制的尺寸相同的图像。如果不是,请尝试通过将图像渲染到某些屏幕外位图上下文来缓存图像,然后将其恢复。
  • 查看CALayer上的shouldRasterize属性。如果您试图操纵其子图层可能构成复杂图层层次结构的图层,则这可能是天赐之物。请务必勾选核心动画工具中的Color Hits Green and Misses Red框,查看您在乐器中的表现。如果你看到很多红色,那么使用shouldRasterize的可能性就会大于帮助。
  • shouldRasterize更好的是展平您的图层层次结构,因为这样可以避免shouldRasterize在实时展平图层层次结构时产生的额外开销。当然这并非总是可行,但不要害怕尝试:)
  • 如果您正在绘制图片,请尝试使用blending mode进行试验。如果您正在绘制不透明图像,则无需使用常规源代码方法(使用读/写带宽)。尝试使用kCGBlendModeCopy,它可以消除读带宽开销。
  • 查看CGLayerRef,它允许您通过对绘图方法的各种调用来缓存Core Graphics输出。我的经验是,除非你正在做一些硬核像素推送,否则这最终会比重绘更昂贵。有关有趣的阅读,请参阅this
  • 最重要的是,乐器是你的朋友。查看过去WWDC中的几个视频(2012, 2011, and 2010);他们都知道如何微调表现。

如果我说的话毫无意义,请随时提出任何问题。