对于性能来说,在iOS上隐藏CALayer还是移除CALayer更好?

5
这与以下问题相关:如何提高CALayer动画的性能? 我目前有一个视图可以拥有数百个CALayer。我知道拥有许多CALayer会因处理器而导致性能下降,但我想看看是否有人尝试了以下几种方法并可以提供指导。
为了更好地让您了解我的意图,想象一下我在图层上画了一个点。当我放大时,我希望该点变成一个星号。当我缩小时,我希望星号回到原来的点。现在想象一下我有数百个这样的点。
单个图层重绘与多个预先绘制的图层
我已经尝试使用两个单独的预先绘制的图层,当缩放改变时,我只需隐藏一个并显示另一个,而不是拥有1个单一的图层进行重绘。
[layer configureWithZoom:zoom];
[layer setNeedsDisplay];

对比

layer1.hidden = (zoom == DEFAULT_ZOOM);
layer2.hidden = (zoom != DEFAULT_ZOOM);

我知道有很多图层会增加我的内存占用,如果以前有50个图层,现在有100个。但就性能而言,这样做会有帮助吗?

隐藏 vs 删除

考虑到上述情况,我现在有一些不需要一直存在的图层。是将这些图层隐藏还是删除比较好呢?

当我想让它消失时,是设置layer.hidden = YES还是使用[layer removeFromSuperlayer]

当我想让它重新出现时,是设置layer.hidden = NO还是使用[superlayer addSublayer:layer]

如果我隐藏了一个图层,但是对超级图层进行动画处理,那么在动画期间因为子图层被隐藏而导致性能受损吗?这种性能损失与添加/删除子图层相比如何?

父图层 vs 直接分层

拥有单独的图层的问题之一是现在我需要编写代码将它们作为一个整体进行管理。以前只需简单地更改图层的位置,例如layer.position = newCoordinates;。现在我需要执行以下操作:

layer1.position = newCoordinates1;
layer2.position = newCoordinates2;

我决定简化这个过程,创建一个父层并将layer1和layer2添加到其中。现在我的主层只需要操作父层而不是单独的层。我的父层还会处理显示或隐藏这两个层的逻辑。
然而,这现在引入了第三个层(一开始我们有1个,现在有3个)。我想知道一个除了其子层之外没有任何实际绘图的层是否会对性能产生影响。换句话说,一个空的层是否与直接将这两个子层添加到超级层中相比,会有性能损失。
感谢您提供的任何指导。
1个回答

11

重绘单个图层 vs 多个预先绘制的图层

这取决于你的绘图方式。我假设你正在使用带有一些自定义代码的CALayer的drawInContext函数?如果是的话,如果不必每次更改缩放级别时都调用此绘图代码,那么肯定会有所帮助。 拥有两倍于以前的图层数所占用的内存空间不应该对你造成影响。

隐藏 vs 删除

我使用了与您类似的设置已经有一段时间了,并且同时在屏幕上有数百(数千)个CALayer。从我的实验中,我发现隐藏图层会导致巨大的性能损失。对我来说,最好的方法总是完全删除它们并稍后重新添加它们。

这真的非常令人沮丧,因为文档中没有提到,通常你永远不会想到隐藏图层会付出(很高的)代价。

父图层 vs 直接分层

关于第三个问题:我不确定作为两个图层的父图层的空图层是否会对性能造成影响,但我猜测它会(根据我的经验,CA必须处理的每个额外图层都会使其运行速度变慢)。 问题是:你能否在无需中间层的情况下完成它?你的图层是否必须按照特定顺序排列?

你可以编写一个自定义类,继承NSObject,接受你的两个图层,并处理它们的一切(更改位置,从superlayer中删除和添加等)。这样,你将拥有一个简单的接口,但屏幕上没有多余的图层。
如果那不是一个选项,你可以尝试使用CATransformLayer作为你两个图层的合成层。该图层除了作为合成层外什么都不做(也可用于3D)。也许在你的情况下,这个图层所占用的性能比“正常”的CALayer要少。

通用性能建议

如果可以的话,请尽量不要使用drawInContext来绘制您的图层。如果可以,使用CAShapeLayer来绘制星星,它速度更快,并且具有很好的抗锯齿效果。

在Xcode中内置的CPU仪表中(而不是分析器),请注意"other processes"的CPU使用情况。在需要大量性能的CA应用程序中,这个"other processes"部分基本上是CA-RenderServer (backboardd)。在这里,您可以看到您当前绘图花费了多少CPU。

否则,如果您关注内存使用情况,请查看分配分析器(这次是真正的分析器)并检查不同版本的代码(50个图层与100个图层)所占用的内存量。


这是非常好的建议,正是我在寻找的。我确实正在使用带有一些自定义代码的drawInContext。绘制星形只是为了我的特定示例。我们实际上正在绘制更复杂的形状以及文本。 - Toland Hon
很高兴听到我能帮助到你! :) - Max
你有兴趣交换邮件地址或Skype ID吗?也许你已经看到了我在CoreAnimation方面遇到的其他问题,反之亦然。 - Max
当然可以。不确定交换联系方式的最佳方式是什么,但您可以在 Twitter 上给我发推文 @krunk4ever。 - Toland Hon

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