framework español iphone objective-c cocoa-touch ios objective-c-blocks

iphone - español - Bloques en lugar de performSelector: withObject: afterDelay:



cocoa touch español (6)

A menudo quiero ejecutar algún código unos 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 todo el tiempo. ¿Es posible usar bloques en lugar de esto? Básicamente estoy buscando un método como:

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

Eso sería realmente útil para mí.


Aquí hay una técnica simple, 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 en GCD, y me interesarían los comentarios sobre esta solución.



No hay una forma incorporada de hacerlo, pero no está mal agregarlo 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

Gracias a Mike Ash por la implementación básica.


Otra forma (quizás la peor forma de hacer esto por muchas razones) es:

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


Si específicamente necesita un retraso mayor, las soluciones anteriores funcionan bien. He utilizado el enfoque de @ nick con gran éxito.

Sin embargo, si solo quiere que su bloque se ejecute durante la siguiente iteración del ciclo principal, puede recortarlo aún más con solo lo siguiente:

[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];

Esto es similar a usar performSelector: con afterDelay de 0.0f


Usé un código similar como este:

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... });