Reputation: 13198
I have an issue showing a UIAlertView
on the main thread. I'm not sure why but it keeps crashing, despite me running on the main thread. The following block is on the background thread, but I have the alert on the main as below:
void (^removeFromCalendar)(NSString *, NSString *, EKEventStore *) = ^(NSString *error, NSString *eventKey, EKEventStore *eventDB) {
EKEvent *myEvent = [eventDB eventWithIdentifier:eventKey];
NSError *err = noErr;
if(myEvent != NULL && myEvent != (id)[NSNull null]) {
[eventDB removeEvent:myEvent span:EKSpanThisEvent error:&err];
} else {
// Event was not found, nothing to do
return;
}
[eventDB release];
if (!err || err == noErr) {
NSLog(@"Deleted event %@", myEvent.title);
// Show alert on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Showing the alert for unattending
NSString *resultString = @"This event was removed from your calendar.";
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Info" message:resultString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil] autorelease];
[alert show];
});
return;
}
error = err.description;
};
If I comment out the bottom where it shows the alert, everything is fine. But for the alert, I keep getting a EXC_BAD_ACCESS
error. Can somebody explain why? It's on the correct thread, and I cant for the life of me understand where the memory issue could come from!
Upvotes: 2
Views: 1466
Reputation: 5935
Instead of using dispatch_async, why not use the objective C call:
[self performSelectorOnMainThread
You might have to package it up in its own method. Alternatively, call it using:
[self performSelector:@selector(myAlertMethod) withObject:nil afterDelay:0.25]
These methods have been tried and true since day 1.
Upvotes: 0
Reputation: 21154
May be you view is being released when you finish until you finish with the background queue. So, for safety why dont you use it like this;
...........
UIViewController __weak *myController = self;
dispathch_async(backgroundQueue, ^{
UIViewController __strong *myStrongController = myController;
...............
dispatch_async(dispatch_get_main_queue(), ^{
if(myStrongController){
// Showing the alert for unattending
NSString *resultString = @"This event was removed from your calendar.";
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Info" message:resultString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil] autorelease];
[alert show];
}
});
}).
Upvotes: 1
Reputation: 3089
This is how you present an alert view:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"<#(NSString *)#>" message:@"<#(NSString *)#>" delegate:self cancelButtonTitle:@"<#(NSString *)#>" otherButtonTitles:nil];
[alert show];
[alert release];
Upvotes: 0