gpt4 book ai didi

ios - 为什么 drawRect : will adversely affect performance during animation 的空实现

转载 作者:可可西里 更新时间:2023-11-01 03:09:03 25 4
gpt4 key购买 nike

我正在子类化我的 UIView 类。 Xcode(我使用的是 4.6.3)自动生成的代码说,

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/

它在我脑海中提出了几个问题:

1) 为什么 drawRect: 的空实现会导致动画期间的不良性能。

2) 我什么时候应该实现drawRect:

3) 如果我正在实现 drawRect: 那么应该采取什么措施作为最佳实践的预防措施。

最佳答案

要了解何时使用 -drawRect: 以及何时使用 UIImageView 等操作,我将不得不做更多解释:

UIView 和CGLayer 本质上是处理固定图片的。这些图像被上传到显卡(如果你了解 OpenGL,可以将图像视为纹理,将 UIView/CGLayer 视为显示这种纹理的多边形)。一旦图像在 GPU 上,它就可以非常快速地绘制,甚至可以绘制多次,并且(具有轻微的性能损失)甚至在其他图像之上具有不同级别的 alpha 透明度。

CoreGraphics/Quartz 是一个用于生成图像的 API。它需要一个像素缓冲区(同样,想想 OpenGL 纹理)并更改其中的各个像素。这一切都发生在 RAM 和 CPU 上,只有在 Quartz 完成后,图像才会“刷新”回 GPU。这种从 GPU 获取图像、更改图像、然后将整个图像(或至少是相对较大的图像 block )上传回 GPU 的往返过程相当缓慢。此外,Quartz 进行的实际绘图虽然对于您正在做的事情来说确实非常快,但比 GPU 做的要慢得多。

这很明显,考虑到 GPU 主要是大块地围绕未更改的像素移动。 Quartz 随机访问像素并与网络、音频等共享 CPU。此外,如果您同时使用 Quartz 绘制多个元素,则必须在更改时重新绘制所有元素,然后上传整个 block ,而如果您更改一张图像,然后让 UIViews 或 CGLayers 将其粘贴到您的其他图像上,您可以将更少量的数据上传到 GPU。

当您不实现 -drawRect: 时,大多数 View 都可以被优化掉。它们不包含任何像素,因此无法绘制任何内容。其他 View ,如 UIImageView,仅绘制一个 UIImage(同样,它本质上是对纹理的引用,可能已经加载到 GPU 上)。因此,如果您使用 UIImageView 绘制同一个 UIImage 5 次,它只上传到 GPU 一次,然后在 5 个不同的位置绘制到显示器,节省了我们的时间和 CPU。

当您实现 -drawRect: 时,这会导致创建一个新图像。然后使用 Quartz 在 CPU 上绘制它。如果您在 drawRect 中绘制 UIImage,它可能会从 GPU 下载图像,将其复制到您要绘制的图像中,完成后,将图像的第二个副本上传回显卡。因此,您在设备上使用了两倍的 GPU 内存。

因此最快的绘制方式通常是将静态内容与变化的内容分开(在单独的 UIViews/UIView 子类/CGLayers 中)。将静态内容作为 UIImage 加载并使用 UIImageView 绘制它,并将在运行时动态生成的内容放在 drawRect 中。如果您有重复绘制的内容,但其本身不会改变(即在同一个插槽中显示 3 个图标以指示某种状态),也可以使用 UIImageView。

一个警告:有太多 UIView 这样的事情。特别透明的区域对 GPU 的绘制造成更大的影响,因为它们在显示时需要与后面的其他像素混合。这就是为什么您可以将 UIView 标记为“不透明”,以向 GPU 表明它可以抹掉该图像后面的所有内容。

如果您的内容在运行时动态生成,但在应用程序的整个生命周期内保持不变(例如,包含用户名的标签),那么使用 Quartz 绘制一次整个内容实际上是有意义的,使用文本、标签的边框等,作为背景的一部分。但这通常是不需要的优化,除非 Instruments 应用程序以不同的方式告诉您。

关于ios - 为什么 drawRect : will adversely affect performance during animation 的空实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18748276/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com