Objective c UIPreviewAction冻结应用程序中的调度信号量

Objective c UIPreviewAction冻结应用程序中的调度信号量,objective-c,xcode,grand-central-dispatch,3dtouch,Objective C,Xcode,Grand Central Dispatch,3dtouch,我使用带有3D触摸的UIPreviewAction调用函数,该函数使用分派信号量来确定异步块何时完成。但是,一旦分派信号涉及到那些被调用的函数,UI就会冻结,或者更确切地说,任何用户输入都会被阻止 如何解决这个问题 先谢谢你,费边 代码示例: UIPreviewAction: UIPreviewAction *action = [UIPreviewAction actionWithTitle:@"Action" style:UIPreviewActionStyleDefault handler

我使用带有3D触摸的
UIPreviewAction
调用函数,该函数使用分派信号量来确定异步块何时完成。但是,一旦分派信号涉及到那些被调用的函数,UI就会冻结,或者更确切地说,任何用户输入都会被阻止

如何解决这个问题

先谢谢你,费边


代码示例: UIPreviewAction:

UIPreviewAction *action = [UIPreviewAction actionWithTitle:@"Action" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
    [(SenderViewController *)self.sender function];
}
被调用的函数:

- (void)function {

    dispatch_semaphore_t sema2 = dispatch_semaphore_create(0);

    BOOL selected = false;

    UIAlertController *enterPasswordAlert = [UIAlertController alertControllerWithTitle:alertTitle message:alertMessage preferredStyle:UIAlertControllerStyleAlert];
    [enterPasswordAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        dispatch_semaphore_signal(sema2);
    }]];
    [enterPasswordAlert addAction:[UIAlertAction actionWithTitle:@"Action" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        selected = true;
        dispatch_semaphore_signal(sema2);
    }]];
    [self presentViewController:enterPasswordAlert animated:true completion:nil];



    while (dispatch_semaphore_wait(sema2, DISPATCH_TIME_NOW)) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    }

    if (!selected) return;
}

为了解决这个问题,我用瓦迪安提供的解决方案解决了这个问题。我只需使用一个分派组,并在分派组通知的执行块中抛出我的代码,该代码应在选择发生后执行。

要解决此问题,我已使用vadian提供的解决方案解决了此问题。我只需使用一个调度组,并将我的代码(应该在选择发生后执行)抛出到调度组通知的执行块中。

dispatch\u semaphore\t冻结应用程序,直到您没有收到响应为止。如果仍然冻结,则尝试添加调度信号量信号(信号2);在dispatch_queue_main()中。这不会改变任何内容。。。UI仍被阻止,无法与UIAlertController交互。请学习了解
UIAlertController
的异步行为。使用完成处理程序并运行应该在完成处理程序中的
函数
返回后运行的代码。在这种情况下,这是对信号灯的误用。好吧,我理解。但我有另一个例子,我不使用UIAlertController,而是使用for循环,其中调用了几个带有完成处理程序的异步方法,然后当循环中的所有异步方法完成时,应执行其他代码。然后使用调度组,而不是信号量或
NSOperation(Queue)
dispatch\u semaphore\t将冻结应用程序,直到您尚未收到响应为止。如果仍然冻结,则尝试添加调度信号量信号(信号2);在dispatch_queue_main()中。这不会改变任何内容。。。UI仍被阻止,无法与UIAlertController交互。请学习了解
UIAlertController
的异步行为。使用完成处理程序并运行应该在完成处理程序中的
函数
返回后运行的代码。在这种情况下,这是对信号灯的误用。好吧,我理解。但我有另一个例子,我不使用UIAlertController,而是使用for循环,其中调用了几个带有完成处理程序的异步方法,然后当循环中的所有异步方法完成时,应执行其他代码。然后使用调度组而不是信号量或
NSOperation(Queue)