检查 NSAlert 当前是否出现

Ran*_*ndy 3 macos cocoa nsalert swift

我正在使用 anNSAlert在我的应用程序的主屏幕上显示错误消息。基本上,这NSAlert是我的主视图控制器的一个属性

class ViewController: NSViewController {

    var alert: NSAlert?

    ...

}
Run Code Online (Sandbox Code Playgroud)

当我收到一些通知时,我会显示一些消息

func operationDidFail(notification: NSNotification)
{
    dispatch_async(dispatch_get_main_queue(), {

        self.alert = NSAlert()
        self.alert.messageText = "Operation failed"
        alert.runModal();
    })
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我收到多个通知,每个通知都会显示警报。我的意思是,它与第一条消息一起显示,我单击“确定”,它消失,然后再次与第二条消息一起显示等等......这是正常行为。

我想要实现的是避免这一系列错误消息。其实我只关心第一个。有没有办法知道我的警报视图当前是否正在显示?就像alert.isVisible在 iOS 上一样UIAlertView

Bor*_*kyi 5

从您的代码中,我怀疑通知是在后台线程中触发的。在这种情况下,任何警报现在可见的检查都无济于事。在第一个块完成之前,您的代码不会开始后续块执行,因为runModal方法将阻塞,NSRunLoop以模式模式运行。

要解决您的问题,您可以引入 atomic bool 属性并在dispatch_async.

Objective-C 解决方案:

- (void)operationDidFail:(NSNotification *)note {
    if (!self.alertDispatched) {
        self.alertDispatched = YES;
        dispatch_async(dispatch_get_main_queue(), ^{
            self.alert = [NSAlert new];
            self.alert.messageText = @"Operation failed";
            [self.alert runModal];
            self.alertDispatched = NO;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 Swift 的相同代码:

func operationDidFail(notification: NSNotification)
{
    if !self.alertDispatched {
        self.alertDispatched = true
        dispatch_async(dispatch_get_main_queue(), {
            self.alert = NSAlert()
            self.alert.messageText = "Operation failed"
            self.alert.runModal();
            self.alertDispatched = false
        })
    }
}
Run Code Online (Sandbox Code Playgroud)