Quiero pausar mi aplicación en cierto punto. En otras palabras, quiero que mi aplicación ejecute el código, pero luego, en cierto punto, haga una pausa de 4 segundos y luego continúe con el resto del código. ¿Cómo puedo hacer esto?
Estoy usando Swift
Respuestas:
En lugar de una suspensión, que bloqueará su programa si se llama desde el hilo de la interfaz de usuario, considere usar
NSTimer
un temporizador de envío.Pero, si realmente necesita un retraso en el hilo actual:
Esto usa la
sleep
función de UNIX.fuente
dispatch_after
En la mayoría de los casos, usar un bloque es mejor que usarlo,sleep(time)
ya que el hilo en el que se realiza el sueño no puede realizar otro trabajo. cuando se utilizadispatch_after
el hilo en el que se trabaja no se bloquea, por lo que puede hacer otro trabajo mientras tanto.Si está trabajando en el hilo principal de su aplicación, el uso
sleep(time)
es malo para la experiencia del usuario de su aplicación ya que la interfaz de usuario no responde durante ese tiempo.Despachar después de programar la ejecución de un bloque de código en lugar de congelar el hilo:
Swift ≥ 3.0
Swift <3.0
fuente
.now() + .seconds(4)
da error:expression type is ambiguous without more context
.now() + .seconds(5)
es simplemente.now() + 5
Comparación entre diferentes enfoques en swift 3.0
1. dormir
Este método no tiene una devolución de llamada. Poner códigos directamente después de esta línea para ejecutar en 4 segundos. Evitará que el usuario itere con elementos de la interfaz de usuario como el botón de prueba hasta que se acabe el tiempo. Aunque el botón se congela cuando se activa el sueño, otros elementos, como el indicador de actividad, siguen girando sin congelarse. No puede activar esta acción nuevamente durante el sueño.
2. Despacho, realización y temporizador
Estos tres métodos funcionan de manera similar, todos se ejecutan en el subproceso de fondo con devoluciones de llamadas, solo con una sintaxis diferente y características ligeramente diferentes.
Dispatch se usa comúnmente para ejecutar algo en el hilo de fondo. Tiene la devolución de llamada como parte de la llamada de función
Realizar es en realidad un temporizador simplificado. Configura un temporizador con el retraso, y luego activa la función con el selector.
Y finalmente, el temporizador también proporciona la capacidad de repetir la devolución de llamada, lo que no es útil en este caso
Para todos estos tres métodos, cuando hace clic en el botón para activarlos, la IU no se congelará y podrá volver a hacer clic en él. Si vuelve a hacer clic en el botón, se configura otro temporizador y la devolución de llamada se activará dos veces.
En conclusión
Ninguno de los cuatro métodos funciona lo suficientemente bien solo.
sleep
desactivará la interacción del usuario, por lo que la pantalla se " congela " (en realidad no) y da como resultado una mala experiencia del usuario. Los otros tres métodos no congelarán la pantalla, pero puede activarlos varias veces, y la mayoría de las veces, desea esperar hasta que reciba la llamada antes de permitir que el usuario realice la llamada nuevamente.Por lo tanto, un mejor diseño utilizará uno de los tres métodos asíncronos con bloqueo de pantalla. Cuando el usuario haga clic en el botón, cubra toda la pantalla con una vista translúcida con un indicador de actividad giratoria en la parte superior, que le indica al usuario que se está manejando el botón. Luego, elimine la vista y el indicador en la función de devolución de llamada, diciéndole al usuario que la acción se maneja correctamente, etc.
fuente
@objc
delante de la función de devolución de llamada para laperform(...)
opción. Así:@objc func callback() {
Estoy de acuerdo con Palle en que usar
dispatch_after
es una buena opción aquí. Pero probablemente no le gusten las llamadas GCD, ya que son bastante molestas de escribir . En su lugar, puede agregar este útil ayudante :Ahora simplemente retrasa su código en un hilo de fondo como este:
Retrasar el código en el hilo principal es aún más simple:
Si prefiere un Framework que también tenga algunas características más útiles, entonces consulte HandySwift . Puede agregarlo a su proyecto a través de Cartago o Accio y luego usarlo exactamente como en los ejemplos anteriores:
fuente
DispatchTime
no estaba disponible en Swift 2. Eralet dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
antes.También puedes hacer esto con Swift 3.
Realice la función después del retraso así.
fuente
En Swift 4.2 y Xcode 10.1
Tienes 4 formas en total para retrasar. Fuera de estas opciones 1 es preferible llamar o ejecutar una función después de un tiempo. El sueño () es menos caso en uso.
Opción 1.
Opcion 2.
Opcion 3.
Opcion 4.
Si desea llamar a una función después de un tiempo para ejecutar algo, no use el modo de suspensión .
fuente
NSTimer
La respuesta de @nneonneo sugirió usar,
NSTimer
pero no mostró cómo hacerlo. Esta es la sintaxis básica:Aquí hay un proyecto muy simple para mostrar cómo podría usarse. Cuando se presiona un botón, se inicia un temporizador que llamará a una función después de un retraso de medio segundo.
Usar
dispatch_time
(como en la respuesta de Palle ) es otra opción válida. Sin embargo, es difícil de cancelar . ConNSTimer
, para cancelar un evento retrasado antes de que ocurra, todo lo que necesita hacer es llamarEl uso
sleep
no se recomienda, sobre todo en el hilo principal, ya que detiene todo el trabajo que se realiza en el hilo.Vea aquí para mi respuesta más completa.
fuente
Pruebe la siguiente implementación en Swift 3.0
Uso
fuente
Puede crear una extensión para usar la función de retraso fácilmente (Sintaxis: Swift 4.2+)
Cómo usar en UIViewController
fuente
Si necesita establecer un retraso de menos de un segundo, no es necesario configurar el parámetro .seconds. Espero que esto sea útil para alguien.
fuente
fuente
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {/*Do stuff*/}
es probablemente más correcto ✌️Si su código ya se está ejecutando en un hilo de fondo, pause el hilo usando este método en Foundation :
Thread.sleep(forTimeInterval:)
Por ejemplo:
(Consulte otras respuestas para obtener sugerencias cuando su código se ejecuta en el hilo principal).
fuente
Para crear un retraso de tiempo simple, puede importar Darwin y luego usar la suspensión (segundos) para hacer el retraso. Sin embargo, eso solo lleva segundos enteros, por lo que para mediciones más precisas puede importar Darwin y usar usleep (millonésimas de segundo) para una medición muy precisa. Para probar esto, escribí:
Que imprime, luego espera 1 segundo e imprime, luego espera 0,4 segundos y luego imprime. Todo funcionó como se esperaba.
fuente
este es el más simple
fuente