在显示新视图之前,iOS会冻结很多秒

在我的应用程序的主视图中,我有一个表视图和两个原型单元格。 我已经使用故事板为每个单元configuration了segues。 在视图控制器中,我将覆盖prepareForSegue将所选单元格上的信息传递到目标视图。

目标视图不是特别复杂,当然也不需要任何繁重的处理来加载。

问题

当我第一次点击主控制器上的一个单元时,目标视图会在5到40秒的长时间延迟后出现。

编辑#2 :后来的水龙头通常更快

注意:

  • 如果在目标视图出现之前再次敲击同一个单元格,则会触发目标视图立即出现。
  • 如上所述,但点击不同的单元格会导致视图立即显示,但会显示来自第一个单元格的数据。
  • 如上所述,但是点击不同的控件(没有关联的段落)会触发目标视图立即出现。
  • 随后的“点击”通常显示较less的延迟。
  • 时间分析器 – 为了我所能看到的 – 显示在这么多秒的延迟期间绝对没有发生任何事情。
  • 我尝试过不同types的赛车,但没有什么区别
  • 一些println显示,发生以下一系列事件:

    • 在主要观点中,prepareForSegue被执行(没有延迟)
    • 那么目标viewDidLoad被执行(没有延迟)
    • …很长时间…
    • 目的地控制器中的集合和表视图开始调用数据源相关的方法来从控制器获取数据。
    • 该视图终于出现(带有不需要的animation,顺便说一句,但这是一个不同的问题)

从我读过的这个话题中,我怀疑这个问题可能与后台线程中发生的一些上述操作有关。

任何想法我可能做错了什么?

编辑#1 :添加了一些代码

在主视图控制器中,使用故事板链接了链接(CTRL-将两个原型单元格拖到目标视图中)。

代码看起来有点像下面这样:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { var assetIndex = assetsTable.indexPathForSelectedRow()?.row println("prepare for segue - start: \(assets[assetIds[assetIndex!]]!.Name)") if let destination = segue.destinationViewController as? AssetThingsListViewController { destination.bundlesRepository = bundlesRepository! destination.asset = assets[assetIds[assetIndex!]] } println("prepare for segue - end") } 

编辑#3我已经在BitBucket上提供了一个示例项目

我检查了你的项目。 虽然我也找不到其他东西,但我也怀疑这是线程问题。

我设法通过实现tableview的委托来解决这个问题,并在代码中提出新的控制器:

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let destination = storyboard?.instantiateViewControllerWithIdentifier("BuilderToysListViewController") as! BuilderToysListViewController destination.botsRepository = botsRepository! destination.builder = builders[builderIds[indexPath.row]] dispatch_async(dispatch_get_main_queue(), { () -> Void in self.presentViewController(destination, animated: true) { () -> Void in } }) } 

注意你已经设置了视图控制器storyboard id: BuilderToysListViewController并且还设置了tableview委托。 不要忘记删除赛段。

最后在新视图控制器中使视图消失,使用下面的代码:

 @IBAction func backButton(sender: AnyObject) { dismissViewControllerAnimated(true, completion: { () -> Void in }) // performSegueWithIdentifier("segueToysByBuilder", sender: nil) } 

这将允许您正确地closures视图而不是错误地创build一个新视图。

很难说,除非你发布你的代码是响应单元格上的水龙头,并呈现新的视图控制器。

UI变化中长时间延迟(或者UI变化从未发生)的一个常见原因是试图从后台线程进行UI更改。 是否有可能你的代码是调用segue运行在不同的线程? 您可以通过在该代码上设置断点并在中断时观察线程号来轻松地进行分析。 如果线程号为0,则在主线程上运行。 如果是其他线程号码,那就是你的问题。