Objective c 显示警报并等待按钮按下

Objective c 显示警报并等待按钮按下,objective-c,multithreading,grand-central-dispatch,uialertcontroller,nsrunloop,Objective C,Multithreading,Grand Central Dispatch,Uialertcontroller,Nsrunloop,我正在尝试实现一个方法alertAndWait,该方法在从主线程“直接”调用和按如下方式调度时应该可以工作: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ dispatch_sync(dispatch_get_main_queue(), ^{ call alertAndWait ... AlertNWait[9879:164395] Step 1 AlertNW

我正在尝试实现一个方法
alertAndWait
,该方法在从主线程“直接”调用和按如下方式调度时应该可以工作:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    dispatch_sync(dispatch_get_main_queue(), ^{
        call alertAndWait
...
AlertNWait[9879:164395] Step 1
AlertNWait[9879:164395] Step 2
AlertNWait[9879:164395] Step 3
AlertNWait[9879:164395] Step 4
AlertNWait[9879:164395] Step 1
AlertNWait[9879:164395] Step 2
AlertNWait[9879:164395] Step 3
AlertNWait[9879:164395] Step 4
调用
alertAndWait
时,会打开一个警报窗口,当前线程正在(非忙)等待。当按下OK按钮时,警报消失,当前线程继续

我的“解决方案”实际上不能正常工作。我知道原因:并行调度同步块导致死锁。。。但我不知道如何预防

- (void)viewDidAppear:(BOOL)animated {

    // called from main thread
    NSLog(@"Step 1");
    [self alertAndWait];
    NSLog(@"Step 4");

    // called from background thread
    NSLog(@"Step 1");
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        dispatch_sync(dispatch_get_main_queue(), ^{
            [self alertAndWait];
             NSLog(@"Step 4");
        });
    });
}

- (void)alertAndWait {
        NSLog(@"Step 2");
        __block BOOL ok = NO;
        UIAlertController* myAlert = [UIAlertController alertControllerWithTitle:@"Alert"
                                                                         message:@"Please press OK to continue"
                                                                  preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction* continueAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                               handler:^(UIAlertAction * action) {
                                                                   ok=YES;
                                                               }];
        [myAlert addAction:continueAction];
        [self presentViewController:myAlert animated:NO completion:nil];
        while(!ok) {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        };
        NSLog(@"Step 3");
}
预期输出如下所示:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    dispatch_sync(dispatch_get_main_queue(), ^{
        call alertAndWait
...
AlertNWait[9879:164395] Step 1
AlertNWait[9879:164395] Step 2
AlertNWait[9879:164395] Step 3
AlertNWait[9879:164395] Step 4
AlertNWait[9879:164395] Step 1
AlertNWait[9879:164395] Step 2
AlertNWait[9879:164395] Step 3
AlertNWait[9879:164395] Step 4
在第2步之后,当用户按下OK按钮时,警报打开,接着第3步

但现在,当按下OK(第二次)时,日志在“步骤2”后结束:

为了方便您,我已将Xcode项目上载到


是否有办法使
警报和等待按要求工作?谢谢大家!

在这种情况下,您不能等待,但可以将完成块传递给
alertAndWait,以便在解除警报后执行

- (void)viewDidAppear:(BOOL)animated {
    // called from main thread
    NSLog(@"Step 1");
    [self alertAndWait:^() {
        // do whatever you want here
    }];
    NSLog(@"Step 4");
}

- (void)alertAndWait:(void (^)())block {
    UIAlertController* myAlert = ...
    ...
    [self presentViewController:myAlert animated:NO completion:block];
    ...
}

为什么要等?如果设置委托,则在进行选择时将调用这些方法。与此同时,系统可以随心所欲。这是一个基于事件的系统。“为什么要等待?”因为这是我的要求。这是一个基于事件的Cocoa模型的要求?是的。我需要它来调试。谢谢。我知道关于完工街区的事。但我要搜索的是alertAndWait,就像前面提到的一样。alertAndWait在从主线程调用时工作,但在从后台线程“调度”时不工作:dispatch_sync(dispatch_get_main_queue(),^{call alertAndWait。