¿Hay alguna manera de llamar a un bloque con un parámetro primitivo después de un retraso, como usar performSelector:withObject:afterDelay:
pero con un argumento como int
/ double
/ float
?
734
¿Hay alguna manera de llamar a un bloque con un parámetro primitivo después de un retraso, como usar performSelector:withObject:afterDelay:
pero con un argumento como int
/ double
/ float
?
Respuestas:
Creo que lo estás buscando
dispatch_after()
. Requiere que su bloque no acepte parámetros, pero puede dejar que el bloque capture esas variables de su ámbito local.Más: https://developer.apple.com/documentation/dispatch/1452876-dispatch_after
fuente
dispatch_time(DISPATCH_TIME_NOW, 10ull * NSEC_PER_SEC)
fragmento es desagradable. ¿No hay una forma más limpia para esto?dispatch_get_current_queue()
siempre devuelve la cola desde la que se ejecuta el código. Entonces, cuando este código se ejecuta desde el hilo principal, el bloque también se ejecutará en el hilo principal.dispatch_get_current_queue()
ahora está en desusoPuede usar
dispatch_after
para llamar a un bloque más tarde. En Xcode, comience a escribirdispatch_after
yEnter
presione para autocompletar lo siguiente:Aquí hay un ejemplo con dos flotantes como "argumentos". No tiene que confiar en ningún tipo de macro, y la intención del código es bastante clara:
Swift 3, Swift 4
Swift 2
C objetivo
fuente
NSEC_PER_SEC * 0.5
funcionaría igual queNSEC_PER_MSEC * 500
. Si bien tiene razón al notar quedispatch_time
espera un número entero de 64 bits, el valor que espera está en nanosegundos.NSEC_PER_SEC
se define como1000000000ull
, y multiplicar eso con una constante de punto flotante0.5
implícitamente realizaría una aritmética de punto flotante, produciendo500000000.0
, antes de que se convierta explícitamente en un entero de 64 bits. Por lo tanto, es perfectamente aceptable usar una fracción deNSEC_PER_SEC
.¿Qué hay de usar la biblioteca de fragmentos de código incorporada de Xcode?
Actualización para Swift:
Muchos votos positivos me inspiraron para actualizar esta respuesta.
La biblioteca de fragmentos de código Xcode incorporada
dispatch_after
solo tiene unobjective-c
idioma. Las personas también pueden crear su propio fragmento de código personalizado paraSwift
.Escribe esto en Xcode.
Arrastre este código y suéltelo en el área de la biblioteca de fragmentos de código.
Al final de la lista de fragmentos de código, habrá una nueva entidad llamada
My Code Snippet
. Edite esto para un título. Para sugerencias mientras escribe el código X, complete elCompletion Shortcut
.Para obtener más información, consulte Creación de un código de código personalizado .
Actualizar Swift 3
Arrastre este código y suéltelo en el área de la biblioteca de fragmentos de código.
fuente
Ampliando la respuesta de Jaime Cham, creé una categoría NSObject + Blocks como se muestra a continuación. Sentí que estos métodos coincidían mejor con los
performSelector:
métodos existentes de NSObjectNSObject + Blocks.h
NSObject + Blocks.m
y usar así:
fuente
delay
debería ser deNSTimeInterval
(que es adouble
).#import <UIKit/UIKit.h>
no es necesario. Y, no veo por qué- (void)performBlock:(void (^)())block;
podría ser útil, por lo que se puede eliminar del encabezado.Quizás más simple que ir a través de GCD, en una clase en algún lugar (por ejemplo, "Util"), o una Categoría en Objeto:
Para usar:
fuente
Para Swift, he creado una función global, nada especial, utilizando el
dispatch_after
método. Me gusta más, ya que es legible y fácil de usar:Que puedes usar de la siguiente manera:
fuente
after
. Entonces puedes escribir:after(2.0){ print("do somthing") }
Aquí están mis 2 centavos = 5 métodos;)
Me gusta encapsular estos detalles y hacer que AppCode me diga cómo terminar mis oraciones.
fuente
PerformSelector: WithObject siempre toma un objeto, por lo que para pasar argumentos como int / double / float, etc. ... puede usar algo como esto.
// NSNumber es un objeto ...
De la misma manera puede usar [NSNumber numberWithInt:] etc .... y en el método de recepción puede convertir el número a su formato como [número int] o [número doble].
fuente
La función dispatch_after despacha un objeto de bloque a una cola de despacho después de un período de tiempo determinado. Use el siguiente código para realizar algunas tareas relacionadas con la interfaz de usuario después de 2.0 segundos.
En swift 3.0:
fuente
mainQueue,
lugar demainQueue)
Aquí está la forma de Swift 3 de hacer cola después de un retraso.
fuente
Aquí hay un útil ayudante para evitar hacer la molesta llamada GCD una y otra vez:
Ahora simplemente retrasa su código en el hilo principal de esta manera:
Si desea retrasar su código a un hilo diferente :
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 Carthage y luego usarlo exactamente como en los ejemplos anteriores:
fuente
Hay uno agradable en el marco de BlocksKit.
BlocksKit
(y la clase)
BBlocksKit.m
fuente
En swift 3, simplemente podemos usar la función DispatchQueue.main.asyncAfter para activar cualquier función o acción después del retraso de 'n' segundos. Aquí en el código hemos establecido el retraso después de 1 segundo. Llama a cualquier función dentro del cuerpo de esta función que se activará después del retraso de 1 segundo.
fuente
Xcode 10.2 y Swift 5 y superior
fuente
Puede ajustar el argumento en su propia clase o ajustar la llamada al método en un método que no necesita pasarse en el tipo primitivo. Luego llame a ese método después de su retraso, y dentro de ese método realice el selector que desea realizar.
fuente
Así es como puede activar un bloqueo después de un retraso en Swift:
Se incluye como una función estándar en mi repositorio .
fuente
Swift 3 y Xcode 8.3.2
Este código te ayudará, también agrego una explicación
fuente
Creo que el autor no pregunta cómo esperar un tiempo fraccional (retraso), sino cómo pasar un escalar como argumento del selector (con Objeto :) y la forma más rápida en el objetivo moderno C es:
su selector tiene que cambiar su parámetro a NSNumber y recuperar el valor utilizando un selector como floatValue o doubleValue
fuente