2

このコードを実行しようとするとEXEC_BAD_ACCESSエラーが発生し、ユーザーがカレンダーへのアクセスを許可していません。requestAccessToEntityTypeは別のスレッドで実行されますか?その場合、メインスレッドにアクセスしてUIAlertViewを表示するにはどうすればよいですか?

EKEventStore *store = [[EKEventStore alloc] init];
if ([store respondsToSelector:@selector(requestAccessToEntityType:completion:)])
{
    [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
     {
         if ( granted )
         {
             [self readEvents];
         }
         else
         {
             UIAlertView *alert = [[UIAlertView alloc] 
                                      initWithTitle:@"Denied Access To Calendar" 
                                      message:@"Access was denied to the calendar, please go into settings and allow this app access to the calendar!" 
                                      delegate:nil 
                                      cancelButtonTitle:@"Ok" 
                                      otherButtonTitles:nil, 
                                      nil];
             [alert show];
         }
     }];
}
4

2 に答える 2

3

requestAccessToEntityTypeのドキュメントによると

ユーザーがタップしてアクセスを許可または拒否すると、任意のキューで完了ハンドラーが呼び出されます。

そうです、UI スレッドとは別のスレッドにある可能性があります。メイン GUI スレッドからのみアラートを出すことができます。

を調べperformSelectorOnMainThreadます。詳細はこちら: Dispatch_async または performSelectorOnMainThread を使用してメイン スレッドで UI の変更を実行しますか?

于 2013-02-19T17:13:38.490 に答える
2

バックグラウンド スレッドで UIAlertView などの GUI 要素を処理しようとしているためにアプリがクラッシュする理由。メイン スレッドで実行するか、ディスパッチ キューを使用する必要があります。

ディスパッチ キューの使用

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

    dispatch_async(queue, ^{

     //show your UIAlertView here... or any GUI stuff

    });

または、このようにメインスレッドで GUI 要素を表示できます

[alertView performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];

このリンクで、スレッドでの GUI 要素の使用について詳しく知ることができます

于 2013-02-19T17:13:40.307 に答える