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

您的应用程序崩溃的原因是您试图处理您的 GUI 元素,即后台线程中的 UIAlertView,您需要在主线程上运行它或尝试使用调度队列

使用调度队列

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 回答