Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

A menudo me quiere ejecutar algún código de unos pocos microsegundos en el futuro. En este momento, lo resuelvo así:

- (void)someMethod
{
    // some code
}

Y esto:

[self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];

Funciona, pero tengo que crear un nuevo método cada vez. ¿Es posible utilizar bloques en lugar de esto? Básicamente estoy buscando un método como:

[self performBlock:^{
    // some code
} afterDelay:0.1];

Esto sería muy útil para mí.

¿Fue útil?

Solución

No hay una función de modo de hacerlo, pero no es tan malo para agregar a través de una categoría:

@implementation NSObject (PerformBlockAfterDelay)

- (void)performBlock:(void (^)(void))block 
          afterDelay:(NSTimeInterval)delay 
{
    block = [[block copy] autorelease];
    [self performSelector:@selector(fireBlockAfterDelay:) 
               withObject:block 
               afterDelay:delay];
}

- (void)fireBlockAfterDelay:(void (^)(void))block {
    block();
}

@end

Mike Ash para la implementación básica.

Otros consejos

Esta es una técnica sencilla, basada en GCD, que estoy usando:

void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
      dispatch_get_current_queue(), block);
}

No soy un experto GCD, y estaría interesado en los comentarios de esta solución.

Otra forma (tal vez la peor manera de hacer esto por muchas razones) es:

[UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished) {
    //do stuff here
}];

Si usted necesita específicamente un mayor retraso, las soluciones anteriores funcionará bien. He usado @ enfoque de Nick con gran éxito.

Sin embargo, si lo que desea su bloque a ejecutar durante la siguiente iteración del bucle principal, puede recortar hacia abajo aún más con sólo el siguiente:

[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];

Esto es similar al uso de performSelector: con afterDelay de 0.0f

He utilizado un código similar como esto:

double delayInSeconds = 0.2f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
      //whatever you wanted to do here...  
    });

Hay un agradable, categoría completa que se encarga de esta situación aquí:

https://gist.github.com/955123

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top