繁体   English   中英

Swift中的NSAttributedString draw(in:rect)性能不好吗?

[英]NSAttributedString draw(in: rect) in Swift have poor performance?

我有一个UIView ,可能同时在屏幕上包含400-500多个字符串。 而且此UIView是可滚动的。 第一个决定是将UICollectionView与自定义布局一起使用。 UIcollectionView中的项目同时在屏幕上的数量不超过30-50时,此方法UIcollectionView 如果我挤压UIView (按捏手势),并且同时在屏幕上显示100-150多个项目,则尝试滚动时会出现滞后现象(降低帧速率并绘制1帧需要20-50毫秒以上的时间)。

好。 然后,我决定绝对手动绘制UIView 对于绘制形状,我使用CGContext(即使同时绘制1000-2000个形状,效果也很好)。 但是,当我尝试使用NSAttributedString draw(in:rect)绘制许多字符串(100-300)时,滚动时会产生非常糟糕的性能。

绘制50个字符串(帧率还可以,绘制时接近16ms) 在此处输入图片说明

绘制150个字符串(帧率很差,绘制时接近30ms) 在此处输入图片说明

绘制300个字符串(帧率很差,绘制时接近60ms) 在此处输入图片说明

那么,问题是为什么Swift中的NSAttributedString draw(in:rect)性能差? 即使我同时向View添加300 UILabel并尝试滚动其帧速率也是可以的(每帧不超过17ms)。 UILabel如何在屏幕重绘时在内部绘制文本以实现高性能?

在大多数情况下,自己绘制图纸并不能改善性能。

UILabel之所以快速,是因为它必须只绘制一次字符串。 然后,它将绘制的字符串的位图图像保留在其后备存储中。 此后将在每个帧中重复使用。 同样,所有视图位图的合成也将通过GPU完成。

如果您自己绘制图形,则很可能无法从缓存的后备存储中受益。 正如您所注意到的,必须重绘整个视图很慢。 可以通过仅重绘实际更改的部分(使用setNeedsDisplay(rect) )来进行改进,但是在缩放时通常是不可能的。 手动绘制速度很慢,因为用于此目的的所有Core Graphics API在CPU而不是GPU上运行。

您将集合视图与自定义布局一起使用的方法应该能够很好地解决这一问题。 编写性能良好的集合视图布局并不容易,但是有可能。 也许您应该使用仪器对此进行调查,然后问另一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM