2

I have a simple application which was working fine until I added some code which launches a new thread at some point and then tries to show an alert from that thread. Now, the app crashes whenever the code for showing the alert is hit.

UIAlertView * addAlert = [[UIAlertView alloc] initWithTitle:@"New alert"
message:@"Example alert" 
delegate:nil 
cancelButtonTitle:@"Cancel", otherButtonTitles:@"OK", nil];
[addAlert show];
[addAlert release];

My question is: is it possible to display UI elements such as alerts from multiple threads on iOS?

341008
  • 9,862
  • 11
  • 52
  • 84

3 Answers3

4

You definitely don't want to be displaying an alert (or anything UI-related) from any thread other than the main thread. I'd suggest putting your alert code in a function and call one of the performSelectorOnMainThread calls.

- (void) showAlert
{
    UIAlertView * addAlert = [[UIAlertView alloc] initWithTitle:@"New alert"
        message:@"Example alert" 
        delegate:nil 
        cancelButtonTitle:@"Cancel", otherButtonTitles:@"OK", nil];
    [addAlert show];
    [addAlert release];
}

// ... somewhere in the worker thread ...
[self performSelectorOnMainThread:@selector(showAlert) withObject:nil waitUntilDone:NO];
zpasternack
  • 17,838
  • 2
  • 63
  • 81
2

I'm pretty sure that the main thread is the only thread that should be the one that handles UI recognition/drawing things to screen. What I would do if I were in your position would to be either use KVO notifications or implement a protocol that some class subscribes to. Going the protocol route, when you get to the alerting part of your code merely have that thread call its protocol method, the subscribing class will be alerted by having the delegate function triggered and you can easily present whatever you have to in that view via the main thread.

Hope that helps.

Stunner
  • 12,025
  • 12
  • 86
  • 145
0

Better and simple and just one line approach is to call performSelectorOnMainThread method with alertView. In your case try this line

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

instead of

[addAlert show];

It will call show method of Alertview on main thread. No need to write any extra method.