insertSubVIew 需要“很长时间”
Posted
技术标签:
【中文标题】insertSubVIew 需要“很长时间”【英文标题】:insertSubVIew taking a "long" time 【发布时间】:2015-12-17 13:29:29 【问题描述】:在我的容器控制器中,用户可以平移视图以切换到不同的视图。当平移手势开始时,它将新视图控制器的视图添加到视图中:view.insertSubView(view:, atIndex:)
经过一番研究,我注意到这一步大约需要 0.03 秒(而其他的都是 0.001-0.002 秒)。这会导致过渡变得有点僵硬,这有点烦人。
视图控制器是在应用开始时使用故事板作为全局创建的。
此外,这只发生在第一次加载视图时。之后的过渡都流利了。
我可以做些什么来预加载视图,以便在第一次加载时不会花费那么“长时间”?
编辑: 周围环境:
var pendingViewController: UIViewController!
didSet
if let pending = pendingViewController
addChildViewController(pending)
let index = view.subviews.count - 1
NSLog("start insert view test")
view.insertSubview(pending.view, atIndex: index)
NSLog("end insert view test")
pending.didMoveToParentViewController(self)
因为它只发生在第一次加载视图时,我认为问题可能出在viewDidLoad
和viewWillAppear
的某个地方。结果如下所示。只有viewDidLoad
花费了少量时间(0.005 秒)。在到达viewDidLoad
之前有 0.02 秒的间隔,但我不知道它可能是什么。
2015-12-17 15:15:57.116 Valor[777:232799] start insertView view test
2015-12-17 15:15:57.136 Valor[777:232799] start viewDidLoad test
2015-12-17 15:15:57.141 Valor[777:232799] end viewDidLoad test
2015-12-17 15:15:57.142 Valor[777:232799] start viewWillAppear test
2015-12-17 15:15:57.144 Valor[777:232799] end viewWillAppear test
2015-12-17 15:15:57.146 Valor[777:232799] end insertView view test
【问题讨论】:
能否请您显示周围的上下文(插入发生的位置)? 【参考方案1】:使用工具找出慢代码发生的位置,而不是使用时间戳记录语句。这将向您显示(包括系统调用)确切时间花费在哪里。
由于布局原因,插入子视图可能会很慢。但是,您的跟踪(例如)表明时间花费在创建和加载视图控制器的视图上。你说这个视图来自故事板。里面有什么?加载此视图时会触发多少其他事情?使用时间分析器,您将能够分辨出来。它可以是一个简单的东西,就像你给它一个默认值的属性一样,它可能是一个惰性值。
视图控制器是在应用开始时使用故事板作为全局创建的。
如果是这种情况,那么您可以通过执行类似的操作来强制加载视图控制器的视图
let hack = viewcontroller.view
访问视图控制器的view
属性会导致它从情节提要加载视图。
【讨论】:
谢谢,这真的很有用。从时间分析器的结果中,我可以看到在这 30 毫秒内发生了什么:17 毫秒用于加载故事板元素(表格视图、搜索栏和约束),8 毫秒用于`viewDidLoad`,另外 5 毫秒用于插入视图和添加到子视图控制器。似乎我无法改变太多来降低这 30 毫秒,所以我想知道是否有办法在其他地方预加载所有这些? 已更新。这不是我引以为豪的解决方案,但它确实有效 谢谢,除非我更改一半的代码,否则我似乎也无法预加载它。我想我将以编程方式创建视图控制器以减少加载时间。我希望能解决它。 从代码加载通常不会比从故事板加载快多少 您可以尝试在手势发生之前添加视图,让它在用户需要时随时出现【参考方案2】:乍一看,我看到一个奇怪的东西:插入pending.view
的索引。例如,如果您的视图上的视图计数为 5,这意味着其子视图的索引从 0 到 4 不等。然后,您希望将新的子视图放在索引 4 (= 5 - 1) 处,而已经有一个您的视图索引 = 4。AFAICS,您的意思是 5 而不是 4。因此,您应该坚持使用 let index = view.subviews.count
,然后在该索引处插入新视图,或者只使用 view.addSubview(pending.view)
。希望对您有所帮助。
【讨论】:
索引只是一个例子,我认为如果我改变它不会有助于减少加载时间。不过还是谢谢。 我明白了,但请尝试一下。我想,在“已采用”索引处插入视图可能会导致冗余布局和渲染操作。至少不会变得更糟,所以试一试吧:) 谢谢,我已经在顶部试过了,其他的也都试过了;d 遗憾的是,它没有帮助。以上是关于insertSubVIew 需要“很长时间”的主要内容,如果未能解决你的问题,请参考以下文章