CADisplayLink和drawRect

时间:2014-12-10 08:44:37

标签: ios objective-c uiview drawrect cadisplaylink

我需要帮助才能更好地理解CADisplayLinkdrawRect的行为方式,这样我就可以弄清楚如何将应用的帧速率保持在平滑的60fps。到目前为止,我(可能是不正确的)理解如下:

1)CADisplayLink在显示刷新时调用指定的选择器(所谓的“v-sync”事件;大约每16ms)。

2)iOS使用双缓冲,这意味着当显示一个帧缓冲时,我们可以准备(绘制)另一个,并在下一个v-sync事件中交换两个。

3)因此,从显示链接触发时起,我有大约16ms的时间来确保完成下一帧所需的所有计算和绘图,以便在交换缓冲区和屏幕时一切准备就绪刷新。

4)自定义UIView的drawRect方法绘制到后台缓冲区,因此在调用drawRect方法后,下一个v-sync事件会显示任何自定义绘图。

这是真的有效吗? (如果在我完成绘制到后台缓冲区之前发生了下一个v-sync事件会发生什么?)

然后,我应该如何使用CADisplayLink重绘自定义UIViews?我曾尝试在显示链接触发时调用setNeedsDisplay,但是在drawRect方法实际开始之前有一段延迟:

2014-12-10 19:17:21.000 myApp[39487:60b] Display link fired.
2014-12-10 19:17:21.001 myApp[39487:60b] Sending setNeedsDisplay
2014-12-10 19:17:21.012 myApp[39487:60b] drawRect beginning
2014-12-10 19:17:21.013 myApp[39487:60b] drawRect finished
2014-12-10 19:17:21.017 myApp[39487:60b] Display link fired.
2014-12-10 19:17:21.018 myApp[39487:60b] Sending setNeedsDisplay
2014-12-10 19:17:21.029 myApp[39487:60b] drawRect beginning
2014-12-10 19:17:21.031 myApp[39487:60b] drawRect finished
2014-12-10 19:17:21.033 myApp[39487:60b] Display link fired.

这是一个非常简化的示例,在drawRect方法中几乎没有绘图。我的一些更复杂的drawRect可能需要10毫秒才能完成。但是drawRect启动和下一次显示刷新之间只有5毫秒!另外,在显示链接触发和drawRect开始之间显然有“浪费”了整整一毫秒!我该如何利用那段时间?

如果我尝试直接在显示链接选择器中调用drawRect,我会得到类似的结果:

2014-12-10 19:24:41.000 myApp[39495:60b] Display link fired.
2014-12-10 19:24:41.001 myApp[39495:60b] Sending setNeedsDisplay
2014-12-10 19:24:41.002 myApp[39495:60b] drawRect beginning
2014-12-10 19:24:41.003 myApp[39495:60b] drawRect finished
2014-12-10 19:24:41.016 myApp[39495:60b] Display link fired.
2014-12-10 19:24:41.017 myApp[39495:60b] Sending setNeedsDisplay
2014-12-10 19:24:41.018 myApp[39495:60b] drawRect beginning
2014-12-10 19:24:41.020 myApp[39495:60b] drawRect finished
2014-12-10 19:24:41.032 myApp[39495:60b] Display link fired.

现在我的绘图代码似乎有足够的时间来执行。但是,Apple文档明确声明“您不应该直接调用drawRect方法”。那么为什么这是错误的呢?如何最大限度地利用每帧画出的16毫秒?

0 个答案:

没有答案