问题
Part of my app requires calendar access, which requires a call to the EKEventStore
method -(void)requestAccessToEntityType:(EKEntityType)entityType completion:(EKEventStoreRequestAccessCompletionHandler)completion
as of iOS 7.
I added the request, and everything runs smoothly if the user selects to allow access, but a problem arises if the user denies or has previously denied access. I added a UIAlertView
to notify the user if access is denied, but the UIAlertView
consistently takes 20-30 seconds to appear, and completely disables the UI during that time. Debugging has shown that [alertView show]
runs before the delay, even though it doesn't actually show until after the delay.
Why is this delay happening and how can I remove it?
[eventStore requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
if (granted) {
[self createCalendarEvent];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Calendar Access Denied"
message:@"Please enable access in Privacy Settings to use this feature."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
}];
回答1:
[alertView show]
is not thread safe, so it is adding its UI change to the queue from which the completion block was dispatched rather than the main queue. I resolved this issue by adding dispatch_async(dispatch_get_main_queue(), ^{});
around the code inside the completion block:
[eventStore requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (granted) {
[self createCalendarEvent];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Calendar Access Denied"
message:@"Please enable access in Privacy Settings to use this feature."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
});
}];
来源:https://stackoverflow.com/questions/22333584/uialertview-takes-a-long-time-to-appear-when-called-in-a-completion-block