iOS 6以降で画面遷移がなぜか数秒かかる件について

ネットワークアプリをiOS で開発していたのだが、
UIAlertView や UIAlertController (iOS 8以降)  が表示されるのに数秒かかったり、
navigationController.pushViewController で画面遷移するのに異常に時間がかかったりする謎現象に襲われて困っていた。

iOS6/7のviewDidLoadが呼ばれるタイミングの違い - なるようになるといいね

つまるところ、iOS6ではpushViewController:animated:やpresentViewController:animated:が実行された時点でviewプロパティにアクセスされ、viewDidLoadがコールされていたのに対して、iOS7ではそのスタックを抜けた時点で初めてviewプロパティにアクセスされるよう変更されました。
遷移処理をその場で行わず、メインスレッドにキューイングするように変更されたのでしょうね。
こんなトラップにハマる人はまずいないと思うのですけど、イニシャライザやviewDidLoadで時間の掛かる処理(ネットワーク通信など)を行い、プログレス表示を行いたい場合、本来は非同期処理にしてコールバックを受け取るような仕組みを作る必要があります

UIAlertView showが遅延するAdd Star - Kazzz の日記

このコードの呼び出しネストが深かったり、スレッドを跨いだりするとすぐに表示せずに、[alert show]実行後表示までに数秒かかったりする。
調べた所、私だけではなく他の方も同様な症状に悩んだ方がたくさんおり、以下のように実行を遅らせることで何故かすぐに表示されることが判った

どうやらこれっぽい。しかも、iOS 8から実装されたUIAlertController でも現象は同じだ。 performSelector はSwift で使えないみたいなのだけど解答があった
iOS8+SwiftでperformSelectorが使えない

func viewSelector(view: ViewController){
let next:UIViewController = UIStoryboard(name:"MainStoryBoard",bundle: nil).instantiateViewControllerWithIdentifier("targetView") as! UIViewController
view.navigationController!.pushViewController(next, animated: true)

}
func delayView(view: ViewController){
let delay = 0.2 * Double(NSEC_PER_SEC)
var time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), {
NSThread.detachNewThreadSelector(Selector("viewSelector:"), toTarget: self, withObject: view)
})

}

こんなコード書いたら10秒かかってたのが2秒で表示されるようになった、なんじゃこりゃ

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です