3

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

class ViewController: NSViewController {

    var alert: NSAlert?

    ...

}

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

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

        self.alert = NSAlert()
        self.alert.messageText = "Operation failed"
        alert.runModal();
    })
}

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

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

4

2 回答 2

5

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

To fix your problem, you can introduce atomic bool property and check it before dispatch_async.

Objective-C solution:

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

Same code using 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
        })
    }
}
于 2016-03-22T15:11:06.333 回答
1

而不是运行模式,您可以尝试

- beginSheetModalForWindow:completionHandler:

来源:https ://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSAlert_Class/#//apple_ref/occ/instm/NSAlert/beginSheetModalForWindow:completionHandler :

在完成处理程序中,将 alert 属性设置为 nil。并且仅在警报属性为 nil 时才显示警报(这将是在解除警报后的每一次)。编辑:我没有看到文档说明您要查找的任何类型的标志。

于 2016-03-22T15:07:12.187 回答