To clarify the purpose of this question: I know HOW to create complicated views with both subviews and using drawRect. I'm trying to fully understand the when's and why's to use one over the other.

我也明白,提前优化那么多,并在进行任何分析之前以更困难的方式做一些事情是没有意义的.考虑到我对这两种方法都很满意,现在我真的很想更深入地了解这两种方法.

我在念力上学到的很多东西都来自于学习如何让表格视图滚动性能变得真正流畅和快速.当然,这个方法的最初来源是iPhone的author behind twitter(以前是twetie).Basically it says that to make table scrolling buttery smooth, the secret is to NOT use subviews, but instead do all the drawing in one custom uiview.从本质上讲,使用大量的子视图似乎会降低渲染速度,因为它们的开销很大,并且会不断地在父视图上重新组合.

To be fair, this was written when the 3GS was pretty brand spankin new, and iDevices have gotten much faster since then. Still this method is regularly suggested on the interwebs and elsewhere for high performance tables. In fact it's a suggested method in Apple's Table Sample Code, has been suggested in several WWDC videos (Practical Drawing for iOS Developers), and many iOS programming books.

甚至还有awesome looking tools个来设计图形并为它们生成核心图形代码.

So at first I'm lead to believe "there’s a reason why Core Graphics exists. It’s FAST!"

但是,一旦我认为我得到了"可能的时候支持核心图形"的 idea ,我就开始意识到,draRect往往是应用程序响应能力差的罪魁祸首,内存非常昂贵,而且真的会给CPU带来负担.基本上,我应该"Avoid overriding drawRect"(WWDC 2012 iOS App Performance: Graphics and Animations)

所以我想,就像所有事情一样,这很复杂.也许你可以帮助我自己和其他人理解使用drawRect的时间和原因?

我发现使用核心图形有两种明显的情况:

  1. 您有动态数据(苹果的股票图表示例)
  2. 你有一个灵活的UI元素,不能用一个简单的可调整大小的图像来执行
  3. 您正在创建一个动态图形,渲染后可在多个位置使用该图形

我看到了避免核心显卡的情况:

  1. 您的视图属性需要单独设置动画
  2. 您的视图层次 struct 相对较小,因此任何使用CG的额外工作都是不值得的
  3. 您希望更新视图的各个部分,而不重新绘制整个视图
  4. 当父视图大小更改时,需要更新子视图的布局

So bestow your knowledge. In what situations do you reach for drawRect/Core Graphics (that could also be accomplished with subviews)? What factors lead you to that decision? How/Why is drawing in one custom view recommended for buttery smooth table cell scrolling, yet Apple advises drawRect against for performance reasons in general? What about simple background images (when do you create them with CG vs using a resizable png image)?

制作有价值的应用程序可能不需要对这个主题有深刻的理解,但我不喜欢在不能解释原因的情况下在两种技术之间进行 Select .我的大脑开始生我的气.

问题更新

谢谢大家提供的信息.这里有一些澄清的问题:

  1. 如果您正在使用核心图形绘制一些东西,但是可以使用UIImageViews和预渲染的PNG来完成相同的事情,那么您是否应该总是这样做呢?
  2. 类似的问题:尤其是在badass tools like this的时候,你应该考虑在核心图形中绘制界面元素吗?(可能是当您的元素显示可变时.例如,一个按钮有20种不同的 colored颜色 变化.还有其他情况吗?)
  3. 根据我在下面回答中的理解,通过在复杂的UIView渲染本身之后有效地捕获单元格的快照位图,并在滚动和隐藏复杂视图的同时显示该快照位图,是否有可能获得表格单元格的相同性能提升?显然,有些部分需要解决.我有一个有趣的 idea .

推荐答案

尽可能使用UIKit和子视图.您可以提高工作效率,并利用所有OO机制,使事情更容易维护.当您无法从UIKit获得所需的性能时,或者您知道try 在UIKit中拼凑绘图效果会更加复杂时,请使用核心图形.

一般的工作流程应该是使用子视图构建表视图.使用仪器测量你的应用将支持的最旧硬件上的帧速率.如果你不能达到60fps,那就下拉到CoreGraphics.当您这样做了一段时间后,您会感觉到UIKit可能是在浪费时间.

那么,为什么Core Graphics速度如此之快呢?

CoreGraphics并不是很快.如果它一直在使用,那么您的速度可能会很慢.它是一个丰富的绘图API,这要求它的工作在CPU上完成,而不是将大量的UIKit工作卸载到GPU上.如果您必须为在屏幕上移动的球设置动画,那么每秒在视图上调用setNeedsDisplay 60次将是一个糟糕的 idea .因此,如果视图中有需要单独设置动画的子组件,则每个组件都应该是一个单独的层.

另一个问题是,当您不使用draRect进行自定义绘制时,UIKit可以优化常用视图,从而使draRect成为无操作的,或者它可以使用合成的快捷方式.当您重写drawRect时,UIKit必须采用慢速路径,因为它不知道您在做什么.

在表格视图单元格的情况下,这两个问题的好处可能会超过这两个问题.当视图第一次出现在屏幕上时,调用drawRect后,内容被缓存,滚动是由GPU执行的简单翻译.因为您要处理的是单个视图,而不是复杂的层次 struct ,所以UIKit的drawRect优化就变得不那么重要了.因此,瓶颈变成了您可以在多大程度上优化您的核心图形绘制.

尽可能使用UIKit.执行最简单有效的实现.轮廓当有激励时,进行优化.

Ios相关问答推荐

缺少预期的键:';NSPrival yCollectedDataTypes';

阿拉伯文变音符号(Harakat)在文本对齐的UILabel中未对齐

有没有办法将滚动视图RTL(阿拉伯语)与Ltr动画一起使用?

如何防止UITest套件与Fastlane一起执行?

Apple Metal iOS 为什么 GLKMatrix4MakeLookAt 来回摇摆

ionic 4 - 编译 ios - 来自项目Pods的目标GoogleDataTransport中的问题

如何在 SwiftUI 视图中显示协议视图?

我需要二进制文件来进行 App Store 应用程序传输吗?

错误:无法根据成员environmentObject推断上下文基础

.onChange(of: ) 一次用于多个 @State 属性?

为什么我的应用在 Testflight 中没有下载 dSYM 按钮?

检测 iOS UIDevice 方向

如何在 OS X 或 iOS(不使用格式塔)中确定运行时的操作系统版本?

从 NSUserDefaults 字典 iOS 中删除所有键

iOS Swift - 获取当前本地时间和日期时间戳

用户拒绝使用后如何提示用户打开位置服务

iOS 7 半透明模态视图控制器

iOS:设备旋转后如何运行函数(Swift)

从 UIScrollview 中删除内容和框架布局指南

Swift - 获取设备的 WIFI IP 地址