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)
        
    

因为它只发生在第一次加载视图时,我认为问题可能出在viewDidLoadviewWillAppear 的某个地方。结果如下所示。只有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 需要“很长时间”的主要内容,如果未能解决你的问题,请参考以下文章

ExportAsFixedFormat 需要很长时间[关闭]

简单的选择需要很长时间才能执行

解释计划需要很长时间

Linq 更新需要很长时间来处理

查询需要很长时间

解包依赖项需要很长时间