西海岸より

つらつらざつざつと

UIAlertViewの表示タイミングがずれる問題

アプリ開発をしていると、何気なくUIAlertViewを使っているけれど、タイミングによっては表示がずれて、意図していないタイミングで表示されることがある。
結構苦しめられたが、やっと再現方法がわかったので備忘メモ。

現象としては、「UIAlertViewのshowをコールするメソッドの処理中にホームボタンで再起動すると、AlertViewは表示されず、別のAlertViewを表示し閉じた後につられて先ほど表示されなかったAlertViewが表示される」というもの。

具体的なサンプルは以下の通り。

サンプル

  1. 以下のような画面のアプリを用意。

上のボタン:すぐにAlertを表示
下のボタン:3秒間処理した後にAlertを表示


//Show Alert View (NOW)ボタンのアクション
- (IBAction)tappedShowAlertViewNow:(id)sender {	
	UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"TestAlert(NOW)"
														message:@"This is a test alert."
													   delegate:self
											  cancelButtonTitle:nil
											  otherButtonTitles:@"close", nil];
	[alertView show];
	[alertView release];
}

//Show Alert View (Delay)ボタンのアクション
- (IBAction)tappedShowAlertViewDelay:(id)sender {
	sleep(3);
	UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"TestAlert(Delay)"
														message:@"This is a test alert."
													   delegate:self
											  cancelButtonTitle:nil
											  otherButtonTitles:@"close", nil];
	[alertView show];
	[alertView release];
}
  1. Delay側のボタンをタップ


  1. ホームボタンを押してアプリを停止(Delayボタンが青くなっている間に)


  1. すぐにアプリのボタンをタップして起動
  2. そうすると画面が一瞬暗くなり、すぐにもとに戻る。


  1. NOW側のボタンをタップ。するとNOWのAlertが表示


  1. NOWのAlertのcloseボタンを押すと、続けざまにDelayのAlertが表示される。


回避方法

上記の通り、連続した長い処理でAlertViewのshowをコールする場合は気をつけた方がよく、AlertViewのcloseボタンタップをトリガに処理を行う場合には想定しない挙動となる可能性がある。

この現象はiOSの性質(バグ?)っぽいので100%の回避方法は無いが、以下の対策が有効。

  • AlertViewを表示するだけのメソッドを準備し、delayをかけてコール
//Show Alert View (Delay)ボタンのアクション(改善)
- (IBAction)tappedShowAlertViewDelay:(id)sender {
	sleep(3);
	[self performSelector:@selector(showAlertViewDelay) withObject:nil afterDelay:0.001];
}

- (void)showAlertViewDelay {
	UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"TestAlert(Delay)"
														message:@"This is a test alert."
													   delegate:self
											  cancelButtonTitle:nil
											  otherButtonTitles:@"close", nil];
	[alertView show];
	[alertView release];
}
  • AlertViewのcloseボタンタップ時に処理が存在する場合、タイミングがずれても問題ないようにする。

自分の場合、上記2つを対策するとほぼ現象は再現しなくなった。
とりあえずiOS側で近い将来に直ることを求む。