post Image
tableView(_:didSelectRowAt:)にて、modalなSegueをperformSegueすると描画が遅い件は、DispatchQueue.main.asyncで解決できる

現象

  • TableViewCellをタップしてからModalにViewControllerが表示されるまで時間がかかることがある
  • 1秒以上待たされることがある

状況

根本原因がつかめていないため、発生時の状況を記載する。以下に当てはまらない場合でも発生するかもしれない。

  • Modal表示するViewController(以下、ViewController)はperformSegueによって表示される
  • ViewControllerの表示には、2つの経路がある
    • TableViewCellをタップしたときにperformSegueを呼ぶ
    • 別途あるボタンをタップしたときに、IBActionの処理にてperformSegueを呼ぶ
  • TableViewCellをタップしたときだけ、ViewControllerがモーダル表示されるまでに時間がかかることがある
    • viewDidLoadからviewWillAppearまで1秒以上かかっていた(5秒以上かかることも)
    • 描画先のViewControllerは、特に大きな初期化処理をしていない
  • tableView(_:didSelectRowAt:)は、メインスレッドで実行されていた
  • IBActionperformSegueをしても遅くならない

解決法

stackOverflowにて、「俺を信じて試してみてくれ」とある。

ios – performSegueWithIdentifier very slow when segue is modal – Stack Overflow

実際に試したところ、スムーズに描画されるようになった。

// Swift3 記法
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    DispatchQueue.main.async {
        self.performSegue(withIdentifier: "showModal", sender: indexPath)
    }
}

所感

  • なぜdidSelectRowAtperformSegueを呼び出すと問題が起こるのだろうか
  • performSegueは同期的な処理なのだろうか

『 Swift 』Article List