简短的回答:可能只是坚持使用 CALayer 的cornerRadius,直到你看到性能问题。
长答案:
我们首先需要区分“绘图”和“合成”。
在 iOS 上绘图是用像素填充纹理的简单操作(CPU 受限任务)。合成是将所有这些纹理拼合到单个帧中以打印到屏幕上的行为(GPU 受限任务)。一般来说,在滚动或动画时,您主要是在对 GPU 征税,这很好,因为像将所有像素向下移动一个是 GPU 早餐吃的东西。
-drawRect:纯绘图,使用CPU填充纹理。CALayer 的cornerRadius 是在合成步骤中完成的,并强调GPU。
使用 -drawRect: 具有非常高的初始成本(它可能很容易花费超过一帧)和非平凡的内存使用,但之后滚动非常平滑(它现在只是一个纹理,就像任何其他纹理一样)。使用 CALayer 的圆角半径创建一堆具有圆角半径的视图非常快,但是一旦你获得了十几个视图,你就可以告别滚动速度(因为 GPU 不仅需要执行正常的滚动任务,还需要继续将角半径添加回您的视图)。
但不要相信我的话,有一些数学。我调整了Florian Kugler 的基准测试并在运行 iOS 6.1.3 的 iPhone 4S 上运行。我测量最初可以在 1/60 秒内创建多少视图,然后测量在帧速率降至 60fps 以下之前可以动画多少视图。换句话说:前期成本与帧率成本。
| -drawRect:| CALayer的角落Radus
在 16.6 毫秒内呈现的最大视图数 | 5 次观看 | 110 次观看
60fps 动画的最大视图数 | ~400 次观看 | 12 次观看
(请注意,该应用程序因在 500 -drawRect:views 处使用过多内存而被终止)
归根结底,在我自己的项目中,我倾向于尽可能地坚持 CALayer 的cornerRadius。我很少需要几个带有圆角的视图和 -drawRect: 对初始性能的影响太大了。子类化视图只是为了绕过角落。
但无论您最终选择哪种方法,请确保您衡量并注意您的应用程序的流畅度和响应速度,并做出相应的响应。