Edited at

iOS7でレジューム復帰時にアラートダイアログを表示するときの注意点

More than 5 years have passed since last update.

開発担当のタイトルで発生した問題で、忘却防止用の自分メモとして残しておきたいと思います。

UIAlertViewを利用したダイアログは通常使用する場合には問題がないのですが、

レジューム復帰時に”wifi接続がない”警告や”ゲーム進行の為に通信します”表示等で

使用しているとiOS7では高確率でCrashするようになりました。

// コードサンプル(Crashする場合)

self.alertDialog =

[[UIAlertView alloc] initWithTitle: @"hoge hoge"
message: @"Unable to connect to the server."
delegate: self
cancelButtonTitle: nil
otherButtonTitles: nil];

[self.alertDialog addButtonWithTitle: @"Retry"];
[self.alertDialog release];
[self.alertDialog show];

Crashした状況のログを見ると以下のようになっていました。

: Debug Log: UE3SYS:CRASH: appUncaughtExceptionHandler: NSInternalInconsistencyException - -[UIKeyboardTaskQueue performTask:] may only be called from the main thread.

ログからは”メインスレッドからコールしなさい”という内容ですが、iOS6まで正常に動作していたので、

iOS7からレジュームからの復帰の際にメインスレッドから呼び出されてないのでは?という予想をしました。

またWebで調べてみるとStack Over Flowでも同様の報告あり、メインスレッドで"show"をコールすると

修正できるようでした。

http://stackoverflow.com/questions/19162508/uialertview-crash-ios7-assertion-failure

http://stackoverflow.com/questions/19005463/uialertview-makes-the-program-crash

アラートダイアログの"show"を以下のように変更した所、Crashしなくなりました。

dispatch_async(dispatch_get_main_queue(), ^{

[self.alertDialog show];
});

今回はこちらの対応で処理しましたが、実際はダイアログ表示のAPIを変更する方法もありそうなので

時間があれば調べておきたいと思いますが、これに関しては完結したいと思います。