CADisplayLink和drawRect

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

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

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

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

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

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

那么,我应该如何使用CADisplayLink重绘自定义CADisplayLink ? 我曾尝试在显示链接触发时调用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启动和下一次显示刷新之间只有5ms! 此外,显示链接触发和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毫秒?