Search code examples
objective-cxcodegrand-central-dispatch3dtouch

Dispatch semaphore in UIPreviewAction freezes app


I am using a UIPreviewAction with 3D Touch to call a function, which uses a dispatch semaphore for determining when an asynchronous block has finished. But as soon as a dispatch semaphore is involved in those called functions, the UI freezes or rather any user input gets blocked.

How can that problem be solved?

Thanks in advance, Fabian.


Code example:

The UIPreviewAction:

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

The function that gets called:

- (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;
}

Solution

  • To close this question I have solved this problem with the solution provided by vadian. I simply use a dispatch group and throw my code, which should be executed after a selection has occurred, in the execution block from dispatch_group_notify.