我认为任何地方都没有写下规则,但希望这会有所帮助:
首先,让我们澄清一些定义。我认为大多数时候屏幕外渲染与屏幕渲染并不是最重要的问题,因为屏幕外渲染可以和屏幕渲染一样快。主要问题是渲染是在硬件还是软件中完成。
使用图层和视图之间也几乎没有实际区别。视图只是 CALayer 的一个薄包装器,它们在大多数情况下不会引入显着的性能损失。如果你想要一个由 CAShapeLayer 或 CATileLayer 等支持的视图,你可以使用 +layerClass 方法覆盖视图使用的图层类型。
通常,在 iOS 上,像素效果和 Quartz / Core Graphics 绘图不是硬件加速的,而其他大多数东西都是。
以下事情不是硬件加速的,这意味着它们需要在软件中完成(屏幕外):
在 drawRect 中完成的任何事情。如果您的视图有一个drawRect,即使是一个空的,绘图也不是在硬件中完成的,并且会降低性能。
将 shouldRasterize 属性设置为 YES 的任何图层。
任何带有蒙版或阴影的图层。
文本(任何类型,包括 UILabel、CATextLayers、Core Text 等)。
您自己使用 CGContext 进行的任何绘图(屏幕上或屏幕外)。
大多数其他东西都是硬件加速的,所以它们要快得多。但是,这可能并不意味着您认为它确实如此。
与硬件加速绘图相比,上述任何类型的绘图都较慢,但它们不一定会降低您的应用程序的速度,因为它们不需要每帧都发生。例如,第一次在视图上绘制阴影很慢,但绘制后会被缓存,并且只有在视图改变大小或形状时才会重新绘制。
光栅化视图或带有自定义 drawRect 的视图也是如此:视图通常不会在每一帧都重绘,它会绘制一次然后缓存,因此首次设置视图后的性能不会更差,除非bounds 改变或者你调用 setNeedsDisplay 就可以了。
为了获得良好的性能,诀窍是避免使用软件绘图来绘制每一帧都会发生变化的视图。例如,如果您需要动画矢量形状,使用 CAShapeLayer 或 OpenGL 将获得比 drawRect 和 Core Graphics 更好的性能。但是如果你画了一个形状,然后就不需要改变它,它不会有太大的不同。
同样,不要在动画视图上放置阴影,因为它会降低帧速率。但是视图上的阴影不会因帧而异,不会产生太大的负面影响。
要注意的另一件事是减慢视图设置时间。例如,假设您有一页文本,所有文本都带有阴影;最初绘制需要很长时间,因为文本和阴影都需要在软件中呈现,但是一旦绘制它就会很快。因此,您需要在应用程序加载时提前设置此视图,并将其副本保存在内存中,这样用户就不必等待很长时间才能在视图首次出现在屏幕上时显示出来。
这可能是 WWDC 视频中明显矛盾的原因。对于不会改变每一帧的大型复杂视图,在软件中绘制一次(之后它们被缓存并且不需要重绘)将产生比让硬件在每一帧重新合成它们更好的性能,即使第一次绘制会比较慢。
但是对于必须不断重绘的视图,例如表格单元格(这些单元格会被回收,因此每次一个单元格滚动到屏幕外时都必须重新绘制它们,并在它作为不同的行滚动回另一侧时重新使用),软件绘图可能会减慢很多速度。