【问题标题】:iOS segue freeze for many seconds before showing new viewiOS segue 在显示新视图之前冻结了几秒钟
【发布时间】:2015-08-29 16:08:02
【问题描述】:

在我的应用程序的主视图中,我有一个表格视图和两个原型单元格。我已经使用情节提要为每个单元格配置了 segues。在视图控制器中,我重写 prepareForSegue 以将所选单元格的信息传递给目标视图。

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

问题

当我第一次点击主控制器中的单元格时,目标视图会在很长一段时间后出现,从 5 到 40 秒。

编辑#2:随后的点击通常更快

注意:

  • 如果我在目标视图出现之前再次点击同一单元格,则会触发目标视图立即出现。
  • 如上所述,但点击不同的单元格会导致视图立即出现,但包含第一个单元格中的数据。
  • 如上所述,但点击不同的控件(没有关联的转场)会触发目标视图立即出现。
  • 随后的“点击”通常显示较少延迟。
  • 时间分析器 - 就我所见 - 表明在这么多秒的延迟期间绝对没有发生任何事情。
  • 我尝试了不同类型的 segue,但没有任何区别
  • 一些 println 显示发生了以下事件序列:

    • 在主视图中,prepareForSegue 被执行(没有延迟)
    • 然后执行目标 viewDidLoad(无延迟)
    • ...长时间延迟...
    • 目标控制器中的集合和表视图开始调用与数据源相关的方法以从控制器中获取数据。
    • 视图终于出现了(带有不需要的动画,顺便说一句,但这是另一个问题)

根据我阅读的有关此主题的内容,我怀疑该问题可能与后台线程中发生的上述某些操作有关。

知道我做错了什么吗?

EDIT #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")
}

EDIT #3我在BitBucket上提供了一个示例项目

【问题讨论】:

  • 我认为这是一个错误。我以前每次第一次做segue时也会发生这种情况。从 iOS 8 开始。
  • 您是否尝试过在发布模式下运行应用程序?我猜你只会在调试模式下看到这种行为。
  • 不幸的是,它也在发布模式下不断发生。
  • 您能否上传一个示例项目,用最少的代码演示您的问题?另外,您在哪里看到这种行为?设备、模拟器,还是两者兼有?
  • 我在BitBucket上提供了一个示例项目

标签: ios swift uiviewcontroller segue uistoryboardsegue


【解决方案1】:

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

我设法通过为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

        }
    })

}

请注意,您已经设置了视图控制器故事板 ID:BuilderToysListViewController,还设置了 tableview 委托。不要忘记删除转场。

最后要在新视图控制器中关闭视图,请使用以下代码:

@IBAction func backButton(sender: AnyObject)
{
    dismissViewControllerAnimated(true, completion: { () -> Void in

    })
//        performSegueWithIdentifier("segueToysByBuilder", sender: nil)        

}

这将允许您正确关闭视图,而不是错误地创建一个新视图。

【讨论】:

  • 谢谢@pteofil。看来我遇到了 iOS 8 错误。 forums.developer.apple.com/message/12349
  • 谁能解释一下上面的代码在做什么?我有同样的问题,一些水龙头被延迟,而另一些则正常。我不认识 botsRepository 或调度代码,我不想在不理解的情况下将代码集成到我的应用程序中。但是,我确实想要一个没有令人沮丧的延迟的应用程序!有人可以解释这段代码在做什么/为什么有帮助吗?谢谢! @pteofil
  • 上面的代码只是在点击单元格时在代码中呈现新的控制器,而不是仅仅在情节提要中进行设置。在您的情况下,您可以跳过设置 botsRepository 和构建器的部分。它们只是所呈现的相应控制器的属性。但是,dispatch_async 是必需的,它是在特定线程上调用某些代码的方式。对 UI 的所有更改都必须在主线程上进行。通常情况下,故事板中设置的东西就是这种情况。但是有错误,在这种情况下,为了安全起见,我自己在主线程上展示了新的控制器
  • 我不确定这是 iOS 8 特有的错误,我正在构建 iOS 9.0 和 9.1。
  • 谢谢@pteofil。我有同样的问题,这个答案已经解决了。但是我不使用“presentViewController”。我只是使用带有“didSelectRow”的segues。
【解决方案2】:

除非您发布响应单元格上的点击并呈现新视图控制器的代码,否则很难说。

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

【讨论】:

  • 另外,我已经意识到后续的“点击”通常不会延迟,但我刚刚也看到了后续持续延迟的情况。
【解决方案3】:

如果有的话,也值得将代码从 viewWillAppear 移动到 viewDidAppear

【讨论】:

    【解决方案4】:

    通过实现以下内容,我能够使用 Swift 5 为 iOS 13 解决这个问题:

    DispatchQueue.main.async {
         self.performSegue(withIdentifier: "YOURSEGUEID", sender: nil)
    }
    

    里面

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
    

    最终结果

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        DispatchQueue.main.async {
             self.performSegue(withIdentifier: "YOURSEGUEID", sender: nil)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      相关资源
      最近更新 更多