Search code examples
iosmultithreadinguialertviewdispatchperformselector

How to multithred correctly? UIAlertView is not displayed, only gray screen


i have implemented textToSpeech in my project and want to display an alertview while text is spoken. here i am calling the methods for textToSpeech:

//-----before TTS starts i try to display alertView with Cancelbutton  
//[self performSelectorOnMainThread:@selector(alertWhileTTS) withObject:nil waitUntilDone:YES]; //gray view and no alertview
//[self performSelector:@selector(alertWhileTTS)];  //gray view and no alertview
//[self alertWhileTTS];  //gray view and no alertview

//this part here is blocking, no gray screen, 
//after TTS is ready, the alertView is displayed
dispatch_async(dispatch_get_main_queue(), ^{
        //Update UI if you have to
        [self alertWhileTTS];
    });


[[self view] setNeedsDisplay];
[self synthesizeInBackground];
[queue waitUntilAllOperationsAreFinished];
[self setIsSpeaking: false];
[[self view] setNeedsDisplay];  

Here the synthesizeInBackground method(in method synthesize starts the TTS):

- (void) synthesizeInBackground {
    queue = [[NSOperationQueue alloc] init];
    operation = [[NSInvocationOperation alloc] initWithTarget:self 
    selector:@selector(synthesize) object:nil];

    [queue addOperation: operation];
}  

While TTS i want to display an alertView with cancel button. But in my case i am only getting a gray screen without the alertView.

How can i call alertWhileTTS correctly, so the alertView gets displayed?

here is the content of alertWhileTTS:

- (void) alertWhileTTS {
UIAlertView *inboxRead = [[[UIAlertView alloc] initWithTitle:@"Inbox tts..."
                                                    message:nil
                                                   delegate:self
                                          cancelButtonTitle:@"Abbrechen"
                                          otherButtonTitles:nil] autorelease];
inboxRead.tag = 997;

[inboxRead show];
}  

UPDATE see my solution, that works:

[self performSelectorOnMainThread:@selector(alertWhileTTS) withObject:nil waitUntilDone:YES];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) {
        [[self view] setNeedsDisplay];
        [self synthesizeInBackground];
        [queue waitUntilAllOperationsAreFinished];
        [self setIsSpeaking: false];
        [[self view] setNeedsDisplay];

    }); 

Solution

  • Change the alertWithTTsTo

    UIAlertView *inboxRead = [[[UIAlertView alloc] initWithTitle:@"Inbox tts..."
                                                        message:nil
                                                       delegate:self
                                              cancelButtonTitle:@"Abbrechen"
                                              otherButtonTitles:nil] autoRelease];
    inboxRead.tag = 997;
    
    [inboxRead show];
    

    Also dont forget to call the function alertWhileTTS from the main ui thread By doing

     dispatch_async(dispatch_get_main_queue(), ^{
            //Update UI if you have to
            [self alertWhileTTS];
        });