运行循环/ drawRect中的神秘“渐进式减速”问题

这是一个真正的谜。

想象一下,您正在进行在屏幕外绘制复杂图像的传统过程(CGLayer),并且在绘制时间歇性地将图像更新到屏幕上。

如您所知,执行此操作的方法是:在后台运行大型绘图过程,并根据需要调用setNeedsDisplays的前景,从而更新图像。 这是微不足道的,可以通过两行代码实现。

然而,当你这样做时,有一个神秘的问题: 每个绘图周期所花费的时间,每次增加,变得无法使用 。 此外,时间可能不规律地变化。

这是一个已知的iOS错误,还是? 有没有人见过这个?

这是一个非常简单,易于理解的应用程序,可以解决问题:

http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html

输出示例如下。

有谁知道为什么会这样? 这是操作系统非常奇怪的行为。

后来 …… FELZ已经找到了令人震惊的解决方案。 Felz每轮复制一次CGLayer。 这完全阻止了这种奇怪的行为。

然而,仍然没有真正清楚地了解究竟发生了什么:因此从字面上看,当奇怪的问题出现时,使用的时间在哪里?

这是输出的一个很长的例子……

请注意,您有时会得到一个“双重奇异”的结果,如下所示:它表现出“正常”奇怪的行为:每次都会增加时间。 但是,偶尔会有几轮时间“非常快”,然后返回。 怪啊? 此外,如果您在模拟器上运行,请快速单击Mac上不相关的应用程序,以获得“更奇怪”的结果。

尽管费尔兹给出了一个完美的工作答案,但实际的机制仍然是一个谜。

:26:56.697 stepwiseDrawing[5334:1a03] time difference was 0 :26:56.707 stepwiseDrawing[5334:1a03] time difference was 10 :26:56.717 stepwiseDrawing[5334:1a03] time difference was 10 :26:56.744 stepwiseDrawing[5334:1a03] time difference was 27 :26:56.771 stepwiseDrawing[5334:1a03] time difference was 27 :26:56.807 stepwiseDrawing[5334:1a03] time difference was 37 :26:56.829 stepwiseDrawing[5334:1a03] time difference was 22 :26:56.864 stepwiseDrawing[5334:1a03] time difference was 35 :26:56.891 stepwiseDrawing[5334:1a03] time difference was 28 :26:56.936 stepwiseDrawing[5334:1a03] time difference was 45 :26:56.949 stepwiseDrawing[5334:1a03] time difference was 12 :26:56.981 stepwiseDrawing[5334:1a03] time difference was 32 :26:57.008 stepwiseDrawing[5334:1a03] time difference was 27 :26:57.041 stepwiseDrawing[5334:1a03] time difference was 33 :26:57.074 stepwiseDrawing[5334:1a03] time difference was 34 :26:57.109 stepwiseDrawing[5334:1a03] time difference was 34 :26:57.143 stepwiseDrawing[5334:1a03] time difference was 35 :26:57.179 stepwiseDrawing[5334:1a03] time difference was 36 :26:57.220 stepwiseDrawing[5334:1a03] time difference was 42 :26:57.271 stepwiseDrawing[5334:1a03] time difference was 51 :26:57.312 stepwiseDrawing[5334:1a03] time difference was 40 :26:57.356 stepwiseDrawing[5334:1a03] time difference was 45 :26:57.400 stepwiseDrawing[5334:1a03] time difference was 44 :26:57.447 stepwiseDrawing[5334:1a03] time difference was 46 :26:57.493 stepwiseDrawing[5334:1a03] time difference was 46 :26:57.542 stepwiseDrawing[5334:1a03] time difference was 49 :26:57.593 stepwiseDrawing[5334:1a03] time difference was 50 :26:57.707 stepwiseDrawing[5334:1a03] time difference was 114 :26:57.766 stepwiseDrawing[5334:1a03] time difference was 58 :26:57.801 stepwiseDrawing[5334:1a03] time difference was 36 :26:57.856 stepwiseDrawing[5334:1a03] time difference was 55 :26:57.918 stepwiseDrawing[5334:1a03] time difference was 62 :26:57.976 stepwiseDrawing[5334:1a03] time difference was 58 :26:58.039 stepwiseDrawing[5334:1a03] time difference was 62 :26:58.101 stepwiseDrawing[5334:1a03] time difference was 63 :26:58.165 stepwiseDrawing[5334:1a03] time difference was 63 :26:58.229 stepwiseDrawing[5334:1a03] time difference was 64 :26:58.294 stepwiseDrawing[5334:1a03] time difference was 66 :26:58.365 stepwiseDrawing[5334:1a03] time difference was 70 :26:58.436 stepwiseDrawing[5334:1a03] time difference was 72 :26:58.507 stepwiseDrawing[5334:1a03] time difference was 70 :26:58.572 stepwiseDrawing[5334:1a03] time difference was 65 :26:58.652 stepwiseDrawing[5334:1a03] time difference was 81 :26:58.726 stepwiseDrawing[5334:1a03] time difference was 74 :26:58.809 stepwiseDrawing[5334:1a03] time difference was 82 :26:58.879 stepwiseDrawing[5334:1a03] time difference was 70 :26:58.965 stepwiseDrawing[5334:1a03] time difference was 87 :26:59.043 stepwiseDrawing[5334:1a03] time difference was 77 :26:59.126 stepwiseDrawing[5334:1a03] time difference was 83 :26:59.210 stepwiseDrawing[5334:1a03] time difference was 84 :26:59.215 stepwiseDrawing[5334:1a03] time difference was 6 :26:59.310 stepwiseDrawing[5334:1a03] time difference was 95 :26:59.397 stepwiseDrawing[5334:1a03] time difference was 87 :26:59.486 stepwiseDrawing[5334:1a03] time difference was 89 :26:59.577 stepwiseDrawing[5334:1a03] time difference was 91 :26:59.668 stepwiseDrawing[5334:1a03] time difference was 91 :26:59.768 stepwiseDrawing[5334:1a03] time difference was 100 :26:59.856 stepwiseDrawing[5334:1a03] time difference was 88 :26:59.857 stepwiseDrawing[5334:1a03] time difference was 1 :26:59.965 stepwiseDrawing[5334:1a03] time difference was 108 :27:00.064 stepwiseDrawing[5334:1a03] time difference was 100 :27:00.165 stepwiseDrawing[5334:1a03] time difference was 101 :27:00.268 stepwiseDrawing[5334:1a03] time difference was 103 :27:00.371 stepwiseDrawing[5334:1a03] time difference was 103 :27:00.377 stepwiseDrawing[5334:1a03] time difference was 7 :27:00.493 stepwiseDrawing[5334:1a03] time difference was 115 :27:00.601 stepwiseDrawing[5334:1a03] time difference was 108 :27:00.710 stepwiseDrawing[5334:1a03] time difference was 109 :27:00.820 stepwiseDrawing[5334:1a03] time difference was 111 :27:00.939 stepwiseDrawing[5334:1a03] time difference was 119 :27:01.053 stepwiseDrawing[5334:1a03] time difference was 114 :27:01.162 stepwiseDrawing[5334:1a03] time difference was 108 :27:01.278 stepwiseDrawing[5334:1a03] time difference was 116 :27:01.396 stepwiseDrawing[5334:1a03] time difference was 118 :27:01.515 stepwiseDrawing[5334:1a03] time difference was 119 :27:01.637 stepwiseDrawing[5334:1a03] time difference was 122 :27:01.648 stepwiseDrawing[5334:1a03] time difference was 11 :27:01.769 stepwiseDrawing[5334:1a03] time difference was 121 :27:01.775 stepwiseDrawing[5334:1a03] time difference was 6 :27:01.910 stepwiseDrawing[5334:1a03] time difference was 135 :27:01.911 stepwiseDrawing[5334:1a03] time difference was 1 :27:02.045 stepwiseDrawing[5334:1a03] time difference was 134 :27:02.175 stepwiseDrawing[5334:1a03] time difference was 131 :27:02.314 stepwiseDrawing[5334:1a03] time difference was 139 :27:02.441 stepwiseDrawing[5334:1a03] time difference was 127 :27:02.586 stepwiseDrawing[5334:1a03] time difference was 145 :27:02.715 stepwiseDrawing[5334:1a03] time difference was 129 :27:02.853 stepwiseDrawing[5334:1a03] time difference was 138 :27:03.000 stepwiseDrawing[5334:1a03] time difference was 146 :27:03.133 stepwiseDrawing[5334:1a03] time difference was 134 :27:03.276 stepwiseDrawing[5334:1a03] time difference was 142 :27:03.419 stepwiseDrawing[5334:1a03] time difference was 143 :27:03.564 stepwiseDrawing[5334:1a03] time difference was 145 :27:03.717 stepwiseDrawing[5334:1a03] time difference was 153 :27:03.858 stepwiseDrawing[5334:1a03] time difference was 141 :27:04.008 stepwiseDrawing[5334:1a03] time difference was 149 :27:04.159 stepwiseDrawing[5334:1a03] time difference was 151 :27:04.318 stepwiseDrawing[5334:1a03] time difference was 159 :27:04.471 stepwiseDrawing[5334:1a03] time difference was 153 :27:04.620 stepwiseDrawing[5334:1a03] time difference was 149 :27:04.778 stepwiseDrawing[5334:1a03] time difference was 158 :27:04.939 stepwiseDrawing[5334:1a03] time difference was 161 :27:05.098 stepwiseDrawing[5334:1a03] time difference was 160 :27:05.269 stepwiseDrawing[5334:1a03] time difference was 171 :27:05.433 stepwiseDrawing[5334:1a03] time difference was 164 :27:05.600 stepwiseDrawing[5334:1a03] time difference was 166 :27:05.765 stepwiseDrawing[5334:1a03] time difference was 165 :27:05.932 stepwiseDrawing[5334:1a03] time difference was 167 :27:06.107 stepwiseDrawing[5334:1a03] time difference was 175 :27:06.269 stepwiseDrawing[5334:1a03] time difference was 163 :27:06.441 stepwiseDrawing[5334:1a03] time difference was 171 :27:06.617 stepwiseDrawing[5334:1a03] time difference was 176 :27:06.798 stepwiseDrawing[5334:1a03] time difference was 181 :27:06.971 stepwiseDrawing[5334:1a03] time difference was 173 :27:07.154 stepwiseDrawing[5334:1a03] time difference was 183 :27:07.326 stepwiseDrawing[5334:1a03] time difference was 172 :27:07.513 stepwiseDrawing[5334:1a03] time difference was 187 :27:07.689 stepwiseDrawing[5334:1a03] time difference was 176 :27:07.875 stepwiseDrawing[5334:1a03] time difference was 185 :27:08.059 stepwiseDrawing[5334:1a03] time difference was 184 :27:08.251 stepwiseDrawing[5334:1a03] time difference was 192 :27:08.432 stepwiseDrawing[5334:1a03] time difference was 181 :27:08.620 stepwiseDrawing[5334:1a03] time difference was 188 :27:08.811 stepwiseDrawing[5334:1a03] time difference was 190 :27:09.004 stepwiseDrawing[5334:1a03] time difference was 193 :27:09.195 stepwiseDrawing[5334:1a03] time difference was 191 :27:09.393 stepwiseDrawing[5334:1a03] time difference was 198 :27:09.590 stepwiseDrawing[5334:1a03] time difference was 197 :27:09.795 stepwiseDrawing[5334:1a03] time difference was 205 :27:09.989 stepwiseDrawing[5334:1a03] time difference was 193 :27:10.189 stepwiseDrawing[5334:1a03] time difference was 200 :27:10.392 stepwiseDrawing[5334:1a03] time difference was 203 :27:10.600 stepwiseDrawing[5334:1a03] time difference was 208 :27:10.801 stepwiseDrawing[5334:1a03] time difference was 202 :27:11.006 stepwiseDrawing[5334:1a03] time difference was 205 :27:11.220 stepwiseDrawing[5334:1a03] time difference was 213 :27:11.430 stepwiseDrawing[5334:1a03] time difference was 210 :27:11.633 stepwiseDrawing[5334:1a03] time difference was 203 :27:11.843 stepwiseDrawing[5334:1a03] time difference was 210 :27:12.055 stepwiseDrawing[5334:1a03] time difference was 213 :27:12.276 stepwiseDrawing[5334:1a03] time difference was 220 :27:12.484 stepwiseDrawing[5334:1a03] time difference was 208 :27:12.700 stepwiseDrawing[5334:1a03] time difference was 216 :27:12.919 stepwiseDrawing[5334:1a03] time difference was 219 :27:13.145 stepwiseDrawing[5334:1a03] time difference was 226 :27:13.360 stepwiseDrawing[5334:1a03] time difference was 215 :27:13.584 stepwiseDrawing[5334:1a03] time difference was 224 :27:13.813 stepwiseDrawing[5334:1a03] time difference was 229 :27:14.049 stepwiseDrawing[5334:1a03] time difference was 236 :27:14.269 stepwiseDrawing[5334:1a03] time difference was 220 :27:14.496 stepwiseDrawing[5334:1a03] time difference was 228 :27:14.725 stepwiseDrawing[5334:1a03] time difference was 229 :27:14.963 stepwiseDrawing[5334:1a03] time difference was 238 :27:15.196 stepwiseDrawing[5334:1a03] time difference was 232 :27:15.423 stepwiseDrawing[5334:1a03] time difference was 227 :27:15.657 stepwiseDrawing[5334:1a03] time difference was 235 :27:15.901 stepwiseDrawing[5334:1a03] time difference was 243 :27:16.133 stepwiseDrawing[5334:1a03] time difference was 232 :27:16.372 stepwiseDrawing[5334:1a03] time difference was 240 :27:16.613 stepwiseDrawing[5334:1a03] time difference was 241 :27:16.863 stepwiseDrawing[5334:1a03] time difference was 250 :27:17.101 stepwiseDrawing[5334:1a03] time difference was 238 :27:17.346 stepwiseDrawing[5334:1a03] time difference was 245 :27:17.593 stepwiseDrawing[5334:1a03] time difference was 247 :27:17.849 stepwiseDrawing[5334:1a03] time difference was 256 :27:18.093 stepwiseDrawing[5334:1a03] time difference was 244 :27:18.344 stepwiseDrawing[5334:1a03] time difference was 251 :27:18.603 stepwiseDrawing[5334:1a03] time difference was 260 :27:18.854 stepwiseDrawing[5334:1a03] time difference was 251 :27:19.114 stepwiseDrawing[5334:1a03] time difference was 259 :27:19.376 stepwiseDrawing[5334:1a03] time difference was 263 :27:19.646 stepwiseDrawing[5334:1a03] time difference was 270 :27:19.927 stepwiseDrawing[5334:1a03] time difference was 281 :27:20.202 stepwiseDrawing[5334:1a03] time difference was 274 :27:20.460 stepwiseDrawing[5334:1a03] time difference was 259 :27:20.743 stepwiseDrawing[5334:1a03] time difference was 283 :27:21.011 stepwiseDrawing[5334:1a03] time difference was 268 :27:21.281 stepwiseDrawing[5334:1a03] time difference was 270 :27:21.563 stepwiseDrawing[5334:1a03] time difference was 282 :27:21.848 stepwiseDrawing[5334:1a03] time difference was 284 :27:22.126 stepwiseDrawing[5334:1a03] time difference was 278 :27:22.398 stepwiseDrawing[5334:1a03] time difference was 272 :27:22.677 stepwiseDrawing[5334:1a03] time difference was 279 :27:22.970 stepwiseDrawing[5334:1a03] time difference was 293 :27:23.258 stepwiseDrawing[5334:1a03] time difference was 288 :27:23.545 stepwiseDrawing[5334:1a03] time difference was 287 :27:23.834 stepwiseDrawing[5334:1a03] time difference was 289 :27:24.122 stepwiseDrawing[5334:1a03] time difference was 288 :27:24.413 stepwiseDrawing[5334:1a03] time difference was 292 :27:24.708 stepwiseDrawing[5334:1a03] time difference was 295 :27:25.002 stepwiseDrawing[5334:1a03] time difference was 294 :27:25.303 stepwiseDrawing[5334:1a03] time difference was 301 :27:25.585 stepwiseDrawing[5334:1a03] time difference was 282 :27:25.880 stepwiseDrawing[5334:1a03] time difference was 294 :27:26.174 stepwiseDrawing[5334:1a03] time difference was 294 :27:26.470 stepwiseDrawing[5334:1a03] time difference was 296 :27:26.475 stepwiseDrawing[5334:1a03] time difference was 5 :27:26.777 stepwiseDrawing[5334:1a03] time difference was 302 :27:27.077 stepwiseDrawing[5334:1a03] time difference was 299 :27:27.373 stepwiseDrawing[5334:1a03] time difference was 297 

首先让我说这是一个有趣的难题。 我在这个上工作很开心。 不错的问题和很好的示例代码。

以下是我对可能答案的看法:

我看到的问题如下。 CGLayer非常适合重复绘画,因为它们将渲染缓存为平面图像。 将附加操作附加到上下文时,缓存无效。 发生这种情况时,再次渲染CGLayer。 减速是因为代码维护了一个CGLayer( offscreenPrefabCGL ),它在paintActualGutsOfHugeImage的循环的每次迭代中都修改了它的上下文。 因为offscreenPrefabCGL上下文中的操作序列随每个花朵而增长,所以每个渲染都需要更多时间。 这解释了每个显示器的时间增加。

我看到两个解决方案:

  1. 将新渲染剪辑到PaintView中的特定渲染中。 而不是使整个视图无效,只使实际需要重新绘制的CGRect无效。 据我所知,这是@ v01d提出的解决方案。
  2. 展平图层。 而不是持有单个CGLayer,在每次迭代时复制CGLayer。 这样可以在图层中保持一个非常快速渲染的平面图像。

我实施了(2)并取得了良好的效果。 前100朵花更快,然后它将稳定在120毫秒(在设备中)。 我用最多2000朵花测试了我的修改版本。

我的修改版本是:

http://dl.dropbox.com/u/9866261/felz_mod_stepwiseDrawingV2.zip

EDIT2:

这是一个有效的(没有减速)调试项目: http : //bit.ly/eukSgR

这个项目绝不是最佳选择。

这里有趣的是需要位图上下文。 CGLayer缓存您的图像绘制并导致您的渐进式减速。 使用位图上下文,它被强制渲染; 然后你只是将这些像素推送到drawRect:中的UIView的CALayer。

我想要获得更高的速度,你可以使用setNeedsDisplayInRect:来最小化重绘区域。

但是,除了优化或两个优化之外,通过UIView推送像素总是比通过说GL完全在GPU上执行此操作要慢。

作为一项实验,我建议您更新动画进度视图,而不尝试使用或读取未完成的大图像位图或正在进行的图层绘制。 从未完成的合成中读取或绘制到另一个绘图上下文可能会对GPU管道或绘图状态做有趣的事情。 尝试在胡椒方法中绘制其他东西。 一个简单的柜台或什么的。