我想在几天前晚上写一些傻事,我想我会在模拟器上观看元素的动画,只是为了放松。但事实证明,这让我在过去的两天里一直很头疼。
的背景 的
我以为我会在320 X 480的屏幕上的每个像素上画一个随机字母。
我将有一个填充26个字母的数组,并使用arc4Random % 26
提取随机字母。
首先,我使用UIGraphicsBeginImageInContextWithOptions
并将图像添加到图像视图中,该视图将添加为我视图的子视图。
完全没问题。
然后我意识到,为什么要等?让我们做一个2 for循环(外部:480 - >内部:320)
一旦第一个内部循环结束,在dispatch_async
中发送该数组并在drawRect
中绘制,然后在下一次迭代完成时,将其发送到另一个dispatch_async
,依此类推,直到两个循环饰面。
我的痛苦从此开始/后...............
原因:
for-loop太紧,太快了。因此,在发送包含320个元素的数组之后,我最终在dispatch_async
内和for内部for循环中包装2 for循环。
但后来我意识到:通过利用sleep(1);
,它想要更快地绘制。实际上,这比完全不使用sleep(1)
所需的时间更长。超过25秒。
所以,我继续尝试使用GCD
并在只有3200个插槽可用之前创建一个,然后才将semaphore
中的数组发送到dispatch_async
;
问题:
比赛条件。我会得到意想不到的数组超出界限错误。错误不一致;有时它会发生在以后,有时会更快。我认为这与正确使用drawRect
无关。
所以我的问题是:
我知道这可以通过CGD
进行微调和解决。但我只是不知道如何。我在我的智慧结束。
我真正想要的是能够更新屏幕的绘图而不是等待整个事情被绘制。要么在屏幕上用点显示一个点,要么通过chuck卡住而不必调用GCD
,但最好是调用setNeedsDisplay
。
我以为我会剖析绘图元素的各个部分,并将每个部分发送到自己的dispatch_async,每个部分都负责仅绘制其部分,并且由于同时运行,它将在屏幕上快速渲染绘图。
但是,我再一次出于想法而结束了沮丧。
setNeedsDisplayinRect
至于信号量版本,我只需在create和signal中设置一个大数字来调用for(int y = 0; y < 480; y++)
{
for(int x = 0; x < 320; x++)
{
//get a random letter here and insert it into the array (myArray)
}
dispatch_async(myQueue, ^
{
dispatch_async(dispatch_async_get_main_queue(),^
{
[self.myView processRowDrawing:myArray];
}
}
[myArray removeAllObjects];
//as mentioned: I tried to put a sleep() here because the loop is faster the the drawing
}
- (void)processRowDrawing:(NSMutableArray*)array
{
for(x = 0; x < array.count; x++)
{
//cell here `setNeedsDisplayInRect:` to draw a row
}
}
但是由于绘图比for循环慢,所以它没有帮助。
是否可以通过[self.myView processRowDrawing:myArray];
以一种漂亮而优雅的方式解决这个问题,方法是同时对绘图部分进行分区并将其发送到GCD
并让部件在屏幕上逐位显示而不是等待它作为一个整体?
逐行或网格逐格看到它们被绘制?同样,我想在这里使用drawRect
。
一直在失眠。请指教。
P.S。我已经尝试过使用GCD
了。
答案 0 :(得分:1)
这种情况不太可能在并行性方面变得更快。让我们来探索一下......
让我们在简单的单线程案例中分解正在这里完成的“工作”。你在320 * 480网格中的每个像素中绘制了26个字母中的一个(即153,600次)。这没有任何意义,但让我们一起运行它。除非您没有提及其他内容,否则CoreText将缓存渲染任何这些字母时第一次呈现26个字形中的每个字形的所有设置成本。这意味着在第一次渲染之后渲染每个字母的边际成本是不变的。当你将最后一个字母渲染到最后一个像素时,你将一个完全渲染的320 * 480位图移交给UIKit进行显示,你就完成了。这笔费用与这次讨论无关。我们将单个字母的平均边际成本称为一个像素 A 。单线程机箱可以使用的最短时间为153,600 * A 。
现在让我们讨论并行化这个渲染所涉及的内容。让我们说把它分成两个320 x 240像素的瓷砖。在这种情况下,您希望整个任务将花费153,600 * A / 2秒。但是,并行化此工作流程还需要其他成本。就在我的头顶:
我的猜测是长杆将会是#3。为了使并行化显示任何增益,这些额外成本总共必须小于153,600 * A / 2秒。仅划分为两个区块会产生绝对最小的开销。任何进一步的细分只会增加开销量。如果将它分成两个图块并不是更快,当然没有多于两个的图块会更快。
您似乎假设渲染字母的成本使并行性的开销相形见绌。我怀疑你是错的。