【问题标题】:How to multithred correctly? UIAlertView is not displayed, only gray screen如何正确地多线程? UIAlertView 不显示,只有灰屏
【发布时间】:2012-06-05 14:35:58
【问题描述】:

我在我的项目中实现了 textToSpeech,并希望在说出文本时显示警报视图。这里我调用 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];  

这里是 synthesizeInBackground 方法(in 方法synthesize启动 TTS):

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

    [queue addOperation: operation];
}  

在 TTS 时,我想显示带有 cancel 按钮的 alertView。但在我的情况下,我只得到一个没有 alertView 的灰屏。

如何正确调用 alertWhileTTS,以便显示 alertView?

这是alertWhileTTS的内容:

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

[inboxRead show];
}  

更新查看我的解决方案,该解决方案有效:

[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];

    }); 

【问题讨论】:

  • 手动内存管理已经有一段时间了,但我认为您不应该这么快释放警报视图。尝试自动释放它。还要确保在主线程上执行此操作。所有 UI 更改都必须在此处完成。

标签: ios multithreading uialertview dispatch performselector


【解决方案1】:

更改 alertWithTTsTo

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

[inboxRead show];

也不要忘记从主 ui 线程调用函数 alertWhileTTS 通过做

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

【讨论】:

  • 我添加了自动释放,就像 borrrden 说的,也尝试在主线程上调用它。也尝试使用您的dispatch_async 代码,但现在没有灰屏。在 TTS 完成后出现 alertView。
  • 你能告诉我们你在哪里调用 alertWhileTTS 吗?可以把调用函数放上去吗?
  • 查看我的帖子,我在[[self view] setNeedsDisplay]; 之前调用了它,我已经评论了代码。
  • 请尝试以下方法而不是 [self performSelector:@selector(alertWhileTTS)];调用 [self performSelector:@selector(alertWhileTTS) withObject:nil afterDelay:1];
  • 我再次更新了我的代码。还写了正在发生的事情。我不明白为什么在 TTS 之后出现 alertView。
【解决方案2】:

您应该使用自动引用计数 (ARC),因为它会自动释放所有内容。正如 borrden 所说,您(大概)正在快速发布 UIAlertView。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    相关资源
    最近更新 更多