Why is it that after showing an NSAlert
nothing works until I close the NSAlert
?
I was trying to print a statement after the display of an NSAlert
but print
is not working.
Below I have attached my code:
let alert: NSAlert = NSAlert()
alert.messageText = "Hello I am Message text"
alert.informativeText = "i am information"
alert.addButton(withTitle: "OK") // First Button
alert.addButton(withTitle: "Cancel") // 2nd Button
alert.alertStyle = NSAlert.Style.warning
alert.delegate = self
if alert.runModal() == .alertFirstButtonReturn {
print("First Button clicked")
} else {
print("Cancel button clicked")
}
print("after NSAlert >>>>>>> ")
My question is why.
Notice how runModal
returns the result of the modal as a NSModalResponse
. Code after the line alert.runModal()
must be able to access the value that it returns, e.g.
let result = alert.runModal()
print(result)
If the code after runModal
were run as soon as the modal is displayed, what would result
be? The user has not clicked any buttons on the modal yet, so no one knows!
This is why when runModal
is called, code execution kind of just pauses there, at that line, until the user chooses one of the options. runModal
is synchronous and blocking.
Compare this with alert.beginSheetModal
, which accepts a completionHandler
closure, and the modal response is not returned, but passed to the completionHandler
. This allows the code after the call to continue to run while the modal is presented, because the code after the call does not have access to the modal response. Only the code in the completionHandler
does. beginSheetModal
is asynchronous.
If you have something you want to print as soon as the alert is displayed, write it before the runModal
call, and (optionally) wrap it in a DispatchQueue.asyncAfter
/DispatchQueue.async
call, so that your print
is asynchronous.
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
print("Hello")
}
alert.runModal()