¿Por qué después de mostrar un NSAlert nada funciona hasta que cierro el NSAlert?

Intenté imprimir una declaración después de mostrar NSAlert pero print no funciona.

A continuación adjunto mi código:

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 >>>>>>> ")

enter image description here

0
Anup Gupta 6 may. 2020 a las 10:12

2 respuestas

La mejor respuesta

Mi pregunta es por qué.

Observe cómo runModal devuelve el resultado del modal como NSModalResponse. El código después de la línea alert.runModal() debe poder acceder al valor que devuelve, p.

let result = alert.runModal()
print(result)

Si el código después de runModal se ejecutara tan pronto como se muestre el modal , ¿cuál sería result? El usuario aún no ha hecho clic en ningún botón en el modal, ¡así que nadie lo sabe!

Es por eso que cuando se llama a runModal, el tipo de ejecución de código simplemente se detiene allí, en esa línea, hasta que el usuario elige una de las opciones. runModal es síncrono y bloqueo .

Compare esto con alert.beginSheetModal, que acepta un cierre completionHandler, y la respuesta modal no se devuelve, sino que se pasa a completionHandler. Esto permite que el código después de la llamada continúe ejecutándose mientras se presenta el modal, porque el código después de la llamada no tiene acceso a la respuesta modal. Solo el código en completionHandler lo hace. beginSheetModal es asíncrono .


Si tiene algo que desea imprimir tan pronto como se muestre la alerta, escríbalo antes de la llamada runModal y (opcionalmente) envuélvalo en una llamada DispatchQueue.asyncAfter / DispatchQueue.async, para que tu print es asíncrono.

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
    print("Hello")
}
alert.runModal()
2
Sweeper 6 may. 2020 a las 10:02
if alert.runModal()

Esto se ejecuta en la sesión modal de toda la aplicación

Aquí es de doc:

Resumen

Ejecuta la alerta como un cuadro de diálogo modal de aplicación y devuelve la constante que identifica el botón en el que se hizo clic. Declaración

open func runModal() -> NSApplication.ModalResponse

2
Asperi 6 may. 2020 a las 07:22