【问题标题】:For performance, is it better to hide or remove CALayers on iOS?为了性能,在 iOS 上隐藏或删除 CALayers 更好吗?
【发布时间】:2015-01-08 22:14:14
【问题描述】:

这与以下问题有关:How to improve performance of CALayer animations?

我目前有一个可以有数百个 CALayers 的视图。我知道拥有许多 CALayer 会导致处理器限制的性能下降,但我想看看是否有人尝试过以下几种方法并可以提供指导。

为了更好地让您了解我正在尝试做什么,假设我在图层上绘制了一个点。当我放大时,我希望这个点变成一颗星星。当我缩小时,我希望星星回到一个点。现在想象一下,我有数百个这样的点。

重绘单层 vs 多个预绘层

我一直在尝试预先绘制 2 个单独的图层,而不是在缩放更改时重绘 1 个单独的图层,当缩放更改时,我只是隐藏一个并显示另一个。

p>
[layer configureWithZoom:zoom];
[layer setNeedsDisplay];

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

我知道拥有一堆层会增加我的内存占用,如果我之前有 50 层,我现在有 100 层。但就性能而言,这会有所帮助吗?

隐藏与删除

鉴于上述情况,我现在有一些并非任何时候都需要的图层。隐藏这些层还是删除它们更好?

当我希望它消失时设置layer.hidden = YES vs [layer removeFromSuperlayer]

设置layer.hidden = NO vs [superlayer addSublayer:layer] 当我希望它回来时。

如果我隐藏了一个层,但为超级层设置了动画,在动画期间是否会因为子层被隐藏而不是被移除而影响性能?与添加/删除子层相比,这种性能损失如何?

父层与直接分层

现在拥有单独层的问题之一是我需要代码来将它们作为一个单元进行管理。以前更改图层位置就像layer.position = newCoordinates; 一样简单。现在我需要做:

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

我决定简化它并创建一个父层并将 layer1 和 layer2 添加到它。我的主层现在可以只操作父层而不是单个层。我的父层还将处理显示或隐藏 2 层中的哪一层的逻辑。

但是,这现在引入了第 3 层(一开始我们有 1 层,现在我们有 3 层)。我很好奇除了子图层之外没有实际绘图的图层是否会对性能产生任何影响。与将这 2 个子层直接添加到超层相比,具有 2 个子层的空层基本上会影响性能。

任何指导将不胜感激。

【问题讨论】:

    标签: ios performance calayer


    【解决方案1】:

    重绘单层 vs 多个预绘层

    这取决于你在这里如何绘制。我假设您正在使用带有一些自定义代码的 CALayer 的 drawInContext?如果是的话,如果每次更改缩放级别时都不需要调用此绘图代码,那肯定会有所帮助。 像以前一样具有双倍层的内存占用确实不应该在这里伤害您。

    隐藏与删除

    我使用与您类似的设置已经有很长一段时间了,并且屏幕上同时有数百(数千)个 CALayers。从我的实验中,我发现隐藏层会对性能造成巨大影响。对我来说,最好是完全删除并稍后重新添加它们。

    这真的很令人沮丧,因为文档中没有提到它,而且通常你永远不会想到隐藏层会消耗(很多)性能。

    父层与直接分层

    关于您的第三个问题:我不能 100% 确定您的作为两个层的父层的空层是否会影响性能,但我猜它是(根据我的经验,CA 拥有的每个额外层处理会导致它运行得更慢)。 问题是:您是否能够在没有中间层的情况下做到这一点?你的图层是否有一定的顺序?

    您可以编写一个自定义类,子类化 NSObject,它采用您的两个层,并管理有关它们的所有内容(更改位置、从超层中删除和添加等)。这样,您将拥有一个简单的界面,但屏幕上没有额外的图层。

    如果这不是一个选项,您可以尝试使用 CATransformLayer 作为两个图层的合成图层。该层除了作为合成层之外没有任何作用(它可以用于 3D)。在您的场景中,这可能比“普通”CALayer 的性能要低。

    一般性能建议

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

    查看 Xcode 中内置的 CPU 计量器(不是分析器)。在那里,您可以看到“其他进程”的 CPU 使用情况。在需要大量性能的 CA-Apps 中,这个“其他进程”部分基本上是 CA-RenderServer(backboardd)。在这里你可以看到你现在的绘图花费了多少 CPU。

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

    【讨论】:

    • 这是很好的建议,正是我想要的。我确实在使用带有一些自定义代码的 drawInContext。画星星只是为了我的特殊例子。我们实际上是在绘制更复杂的形状以及文本。
    • 我很高兴听到我可以帮助你! :)
    • 您是否有兴趣交换邮件地址或Skype ID?也许您已经看到了我在使用 CoreAnimation 时遇到的其他一些问题,反之亦然。
    • 当然。不知道交换联系信息的最佳方式是什么,但你可以发推给我@krunk4ever。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 2021-12-13
    • 2019-07-20
    • 2015-08-06
    • 2023-01-18
    相关资源
    最近更新 更多