这与以下问题有关:How to improve performance of CALayer animations?
我目前有一个可以有几百个CALayers的视图。我知道有很多CALayers会导致性能下降受到处理器的限制,但是我想知道是否有人在那里尝试了以下几种方法并且可以提供指导。
为了更好地了解我正在尝试做什么,想象一下我的图层上有一个点。当我放大时,我希望点成为一个明星。当我缩小时,我希望明星重新成为一个点。现在想象我有数百个点。
重绘单个图层与多个预先绘制的图层
当缩放发生变化时我没有重新绘制1个单独的图层时,我一直在尝试预先绘制2个单独的图层,当缩放发生变化时,我只是隐藏了一个并显示另一个。
[layer configureWithZoom:zoom];
[layer setNeedsDisplay];
VS
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个子层的空层具有性能损失。
任何指导都将不胜感激。
答案 0 :(得分:9)
重绘单个图层与多个预先绘制的图层
这取决于你如何在这里画画。我假设你使用CALayer的 drawInContext 和一些自定义代码?如果是,如果每次更改缩放级别时都不需要调用此绘图代码,这肯定会有所帮助。 像以前一样拥有双层的内存占用在这里真的不应该伤到你。
隐藏与删除
我现在已经使用类似的设置工作了很长时间,并且在屏幕上同时拥有数百(数千)个CALayers。从我的实验中我发现隐藏层有很大的性能影响。对我来说,最好在以后彻底删除并重新添加它们。
这真的令人沮丧,因为它在文档中没有说出来,而且通常你永远不会认为隐藏层会花费很多(很多)性能。
父级与直接分层
关于你的第三个问题:我不是百分之百确定你的两层作为父级的空图层是否会受到性能影响,但我猜它是(从我的经验来看,每一个额外的层都是CA必须处理它导致它运行得更慢)。 问题是:你能否在没有介于两者之间的情况下做到这一点?你的图层必须有一定的顺序吗?
您可以编写一个自定义类,子类化NSObject,它将占用您的两个层,并管理有关它们的所有内容(更改位置,从超级层中删除和添加等)。这样你就可以有一个简单的界面,但屏幕上没有额外的图层。
如果这不是一个选项,您可以尝试使用 CATransformLayer 作为两个图层的合成图层。该图层不做任何事情,只能作为合成图层(并且可以用于3D)。也许这个比#"普通"您的方案中的CALayer。
一般表现假设
如果可能,请勿使用 drawInContext 绘制图层。如果可以的话,使用 CAShapeLayer 作为你的星星,它会更快,并且具有很好的抗锯齿效果。
看看Xcode内置的CPU计量器(不是探查器)。在那里你可以看到"其他进程的CPU使用情况"。在需要大量性能的CA-Apps中,这个"其他流程" section基本上是CA-RenderServer(backboardd)。在这里,您可以看到您的绘图成本目前有多少CPU。
否则,如果您担心内存使用情况,请查看分配分析器(这次是真正的分析器),并检查代码的不同版本(50对100层)占用多少内存。