2010-02-09 9 views
22

¿Existe alguna manera más directa de esperar una cantidad específica de tiempo en Cocoa que la que se me ocurrió a continuación?Esperando una duración especificada en Cocoa

- (void) buttonPressed { 
    [self makeSomeChanges]; 

    // give the user some visual feedback and wait a bit so he can see it 
    [self displayThoseChangesToTheUser]; 
    [self performSelector:@selector(buttonPressedPart2:) withObject:nil afterDelay:0.35]; 
} 

- (void) buttonPressedPart2: (id)unused { 
    [self automaticallyReturnToPreviousView]; 
} 

Para que quede claro, no hay funcional problema con este código - Mi carne es un estilística uno. En mi caso, el flujo es lo suficientemente simple como para que funcione, pero trate de encapsularlo o agregar algunos condicionales y las cosas podrían ponerse feas. Se ha especie de molestando a mí que no podía encontrar una manera de esperar y luego regresar a ese mismo punto en el código como este (ficticio) ejemplo:

- (void) buttonPressed { 
    [self doStuff]; 
    [UIMagicUnicorn waitForDuration:0.35]; 
    [self doStuffAfterWaiting]; 
} 

Respuesta

61

No es

usleep(1000000); 

y

[NSThread sleepForTimeInterval:1.0f]; 

ambos de los cuales se va a dormir por 1 segundo.

+8

y ambos de los cuales bloquear el hilo de hacer cualquier otra cosa. malo, si está en el U.I. hilo. – pestilence669

+3

Es cierto. Si necesita que la IU responda durante este período, el enfoque sugerido en la pregunta, un disparo NSTimer una vez (como usted sugiere) o un hilo de fondo que realice este retraso sería mejor. –

+0

Gracias - eso es lo que me preguntaba, probablemente habría tropezado con él si 'sueño' hubiera sido uno de los muchos sinónimos de 'espera' que había pensado buscar. Gracias también Pestilence por las advertencias sobre cuándo * no * usar estos. –

2

Es probable que desee utilizar un NSTimer y lo han envíe un mensaje "doStuffAfterWaiting" como devolución de llamada. Cualquier tipo de "sueño" bloqueará el hilo hasta que se despierte. Si está en tu U.I. hilo, hará que su aplicación aparezca "muerta". Incluso si ese no es el caso, es mala forma. El enfoque de devolución de llamada liberará a la CPU para realizar otras tareas hasta que se alcance el intervalo de tiempo especificado.

Este doc tiene ejemplos de uso y analiza las diferencias sobre cómo & dónde crear su temporizador.

Por supuesto, performSelector: afterDelay: hace lo mismo.

3

No estoy seguro si existe (todavía), pero con bloques en 10.6 (o PLBlocks en 10.5 y en el iPhone) debería ser bastante fácil escribir un pequeño contenedor como performBlock:afterDelay: que hace exactamente lo que quiere sin la necesidad de dormir todo el hilo. Sería un pequeño y útil código de verdad.

Mike Ash tiene written about an approach like this on his blog:

NSString *something = ...; 
RunAfterDelay(0, ^{ 
    NSLog(@"%@", something); 
    [self doWorkWithSomething: something]; 
}); 
2

¿Qué pasa con un simple usleep? Quiero decir, excepto por el bien de "Pureza de cacao", todavía es mucho más corto que otras soluciones :)

+2

Bloquea el hilo. Si se llama en general, estás matando efectivamente el ciclo de ejecución y la aplicación aparecerá "muerta" – pestilence669

+3

Luego no llames desde la línea principal – Charlie

10

Esta es la manera NSTimer de hacerlo. Puede ser incluso más feo que el método que estás usando, pero permite repetir eventos, así que lo prefiero.

[NSTimer scheduledTimerWithTimeInterval:0.5f 
           target:self 
           selector: @selector(doSomething:) 
           userInfo:nil 
           repeats:NO]; 

Quiere evitar algo así como usleep() que simplemente cuelgue su aplicación y la haga sentir indiferente.

+1

Creo que quieres decir 'NSTimer', no' NSThread'. –

+7

"' Quieres evitar algo como usleep() que simplemente cuelgue tu aplicación y te haga sentir que no responde. "Bastante seguro de que esto solo es cierto si llamaste a 'usleep' desde el hilo principal. – chown

0

Si no te importa una solución asincrónica, Aquí van:

[[NSOperationQueue currentQueue] addOperationWithBlock:^{ 
    [self doStuffAfterWaiting]; 
}]; 
Cuestiones relacionadas