UIView的性能:removeFromSuperview与hide的比较

26

这个问题非常基础。从视图层级中移除一个UIView和隐藏一个UIView之间有什么性能差异?

我读到过,不需要的视图应该从视图层级中移除。我目前遇到的情况是,一个UIButton有时应该是可见的。什么时候应该隐藏UIButton,什么时候应该将其从其父视图中移除?

改变视图层次结构是否代价高昂?

3个回答

10
我在iOS6的iPad mini上做了一个实验,使用了一个非常大的滚动视图,其中包含了许多丰富的内容(包括图片、阴影、渐变层、图案背景图等),我发现view.hidden=YES并不等同于[view removeFromSuperview]。
我最初认为将hidden设置为YES会使视图不被渲染/绘制,因此有许多隐藏的视图对效率没有任何影响。但实际结果是: 1)如果我将大滚动视图中的屏幕外视图设置为隐藏(并在它们重新进入可见区域时取消隐藏),则滚动不连续/平滑。当自然减速时,它看起来非常跳跃。 2)如果我从滚动视图中移除屏幕外的视图(但仍保留在内存中跟踪数组中,以便它们再次进入时可以立即添加),则滚动显然更加流畅。

3
对我来说,这实际上再次强调了将UIView设置为“hidden”可以避免它被渲染,可能会在某种程度上提高性能。当然,跳动感来自于将其“unhidden”,这可能会强制执行setNeedsDisplay以及setNeedsLayout(后者不确定),这会导致减速。对于tableView来说,这可能是个不好的主意,但对于一个比较大的视图而言,它可能是一个好主意,因为它不需要无谓地触发重绘过程。 - strange
"2)如果我从滚动视图中删除离屏视图(但仍通过跟踪数组在内存中保留,因此当它们重新进入时可以立即添加),则滚动显然更加平滑。"这听起来是一种处理离屏视图的好方法(从内存和性能的角度)。 - Netzer

5
如果您需要在显示和隐藏子视图之间交替,最好的方法肯定是隐藏它。对于 UIButton 来说,内存影响也不是很大。如果您只切换 hidden 属性,那么代码肯定更简单。
此外,使用 hidden 属性还有另一个好处,就是它支持动画效果!

渲染隐藏的UIView和不在视图层次结构中没有该视图之间有什么区别?有区别吗? - bas
是的。如果它已被删除,你基本上需要从头开始重新创建它。这可能有利于内存管理,但对性能来说可能不太好,并且不够美观,因为你无法对变化进行动画处理。 - Mundi
如果您保留对视图的引用,则无需重新创建它。我对更改视图层次结构的开销很感兴趣。这种修改会触发什么?我想它基本上会更改UIKit正在管理的树形结构,作为视图层次结构的表示。您认为这准确吗? - bas
更正一下你关于引用的说法。我认为隐藏方法更有效,正是出于你所述的原因。但是你需要创建一个相当庞大的测试场景才能感受到这种差异。(例如,快速滚动许多表视图单元格...) - Mundi

0

在最初的问题和(理所当然地)被接受的答案之间已经过去了一些年头。让我再添加一个因素:与此同时,苹果公司推出了AutoLayout,据说在某些(深层)子视图层次结构中可能会带来相当大的性能损失。

如果您正在使用AutoLayout,则隐藏的视图仍将被布局,而不是已删除的视图(其引用保存在某个地方)。根据您的情况,这可能会导致性能差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接