テーブル ビューの行が選択されたときにアラートを表示し、そのアラートが消えるまで待機するコードがあります。iOS 5 および 6 を搭載した iPad では問題なく動作しますが、iOS 7 ではアラートを無視しようとしてスタックします。
この問題を説明するために、単純なマスター/詳細アプリを作成し、UIAlertView を拡張して UIAlertViewDelegate に準拠する単純な MyAlert クラスを作成しました。
@interface MyAlert : NSObject <UIAlertViewDelegate>
{
volatile BOOL completed;
UIAlertView * alert;
}
- (void) showAndWaitUntilDone:(NSString*)message;
@終わり
MyAlert.m:
@implementation MyAlert
- (void) showAndWaitUntilDone:(NSString*)message
{
alert = [[UIAlertView alloc] initWithTitle:@"Alert"
message:message
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Other", nil];
if (alert)
{
alert.delegate = self;
[self showAndWaitUnitlDone];
}
}
- (void) showAndWaitUnitlDone
{
completed = NO;
[alert show];
while (!completed)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
completed = YES;
}
@end
次に、次のように ViewController にアラートを表示します。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[MyAlert showAndWaitUntilDone:@"test msg"];
}
の効果:
前述のように、これは iOS 5 および 6 で問題なく動作します。
メイン スレッドをブロックしなければ、すべて正常に動作するように見えますが、たとえば UIButton コールバックからこのコードを実行すると、うまく動作します。