読者です 読者をやめる 読者になる 読者になる

Still Life

残念IT系母ちゃん。旦那さん、娘1歳、猫の4人暮らし。

エラー:Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

iPhone

こんなエラーに悩まされました。

2012-02-21 10:31:54.773 appName[893:207] nested pop animation can result in corrupted navigation bar
2012-02-21 10:31:55.134 appName[893:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

検索すると一番に出てくるページで原因はわかりました。
http://stackoverflow.com/questions/5301014/ios-popviewcontroller-unexpected-behavior

viewDidAppearが実行されていないうちに画面遷移をしてしまっていたのが原因でした。
ある画面Aから別の画面Bに遷移し、再びもとの画面Aに戻ったときに、画面Bでの操作によっては更に別画面Cに遷移する必要があるのですが、画面Cに行くかどうかの判定を画面Aのコールバックメソッド内で行っています。
この判定が、画面AのviewWillAppearよりも先に行われてしまうため、落ちてしまうのです。
わかりにくかったのは、上記エラーは画面BからAに遷移した後に出力されるものの、画面Cへは遷移してしまいます。そして実際に落ちるのは、ユーザーが画面Cから別の画面に遷移しようとするときです。
画面Cの中で問題が何なのか探してしまいました。


いちばん簡単な解決策は、単純に、画面遷移時にアニメーションしないことのようですが、いろんな他のコーディングが邪魔しているのか、アニメーションNOにすると、画面遷移しないまま処理が進むという悲しい事態になりました・・・。


それ以外の手としては、viewDidAppearが終了するときにフラグを立てて感知すれば良さそうですが、viewDidAppearメソッドの開始時と終了時にフラグ操作をしても、うまくいきません。エラー原因になっているコードが、viewWillAppearの開始よりも前に実行されてしまうのです。
さらなる手として、クラスフィールドなフラグを作って、遷移する前にフラグを立てておき、viewDidAppear完了でフラグを落とす。コールバックメソッドでは、while(true){}的に待機をしてみたのですが、whileのところで完全に待機してしまいました(笑)。


ひとまず、かっこよくないのですが、画面Cに遷移するときにタイマーをかませました。
何秒待たせるかですが、0.1秒だとこれまた画面遷移しないまま処理が進むという状態になったので、0.5秒にしました。
デバッグしている限りでは大丈夫そうなのですが、不安です・・・。


iOS開発では初心者の域は抜け出せたかな?と思っていたのですが、まだ道のりは長いようです。