在Swift中自定义UIView的加载时间较慢

背景

为了使文本视图水平滚动以用于垂直蒙古语脚本 ,我创建了一个自定义UIView子类。 该类采用UITextView ,将其置于UIView ,旋转并翻转该视图,然后将该视图放入父UIView

在此处输入图像描述

旋转和翻转的目的是使文本垂直,以便换行可以正常工作。 将所有内容粘贴在父UIView的目的是使自动布局在故事板中起作用。 ( 点击此处查看更多详情。)

我有一个有效的解决方案。 github上的完整代码就在这里 ,但我创建了一个新项目并删除了所有不必要的代码,以便隔离问题。 以下代码仍执行上述基本function,但仍然存在下面描述的慢加载问题。

 import UIKit @IBDesignable class UIMongolTextView: UIView { private var view = UITextView() private var oldWidth: CGFloat = 0 private var oldHeight: CGFloat = 0 @IBInspectable var text: String { get { return view.text } set { view.text = newValue } } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override init(frame: CGRect){ super.init(frame: frame) } override func sizeThatFits(size: CGSize) -> CGSize { // swap the length and width coming in and going out let fitSize = view.sizeThatFits(CGSize(width: size.height, height: size.width)) return CGSize(width: fitSize.height, height: fitSize.width) } override func layoutSubviews() { super.layoutSubviews() // layoutSubviews gets called multiple times, only need it once if self.frame.height == oldHeight && self.frame.width == oldWidth { return } else { oldWidth = self.frame.width oldHeight = self.frame.height } // Remove the old rotation view if self.subviews.count > 0 { self.subviews[0].removeFromSuperview() } // setup rotationView container let rotationView = UIView() rotationView.frame = CGRect(origin: CGPointZero, size: CGSize(width: self.bounds.height, height: self.bounds.width)) rotationView.userInteractionEnabled = true self.addSubview(rotationView) // transform rotationView (so that it covers the same frame as self) rotationView.transform = translateRotateFlip() // add view view.frame = rotationView.bounds rotationView.addSubview(view) } func translateRotateFlip() -> CGAffineTransform { var transform = CGAffineTransformIdentity // translate to new center transform = CGAffineTransformTranslate(transform, (self.bounds.width / 2)-(self.bounds.height / 2), (self.bounds.height / 2)-(self.bounds.width / 2)) // rotate counterclockwise around center transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2)) // flip vertically transform = CGAffineTransformScale(transform, -1, 1) return transform } } 

问题

我注意到自定义视图加载速度非常慢。 我是Xcode Instruments的新手,因此我观看了有用的video调试Xcode和Profiler以及Time Profiler的 内存问题 。

之后我尝试在自己的项目中找到问题。 似乎无论我是使用Time Profiler还是Leaks或Allocations工具,它们都表明我的类init方法做了太多工作。 (但是我已经从之前的缓慢加载时间知道了。)以下是分配工具的屏幕截图:

在此处输入图像描述

我没有扩展所有的调用树,因为它不适合。 为什么要创建这么多对象? 当我创建一个三层自定义视图时,我知道它并不理想,但是看起来从调用树中发生的层数是荒谬的。 我究竟做错了什么?

您不应该在layoutSubviews添加或删除任何子视图,因为这样做会再次触发对layoutSubviews的调用。

在创建视图时创建子视图,然后仅在layoutSubviews调整其位置,而不是删除并重新添加它。