2009-09-29 17 views
10

Para repetir una llamada al método (o enviar mensaje, supongo que el término apropiado es) cada x segundos, es mejor utilizar un NSTimer (de NSTimer scheduledTimerWithTimeInterval: objetivo: Selector: userInfo: repite :) o tener el método recurrentemente se llama a sí mismo al final (usando performSelector: withObject: afterDelay)? Este último no usa un objeto, pero tal vez es menos claro/legible? Además, solo para darle una idea de lo que estoy haciendo, es solo una vista con una etiqueta que cuenta hasta las 12:00 de la medianoche, y cuando llega a 0, parpadea el tiempo (00:00:00) y ejecute un pitido para siempre.iPhone dev - performSelector: withObject: afterDelay o NSTimer?

Gracias.

Editar: también, ¿cuál sería la mejor manera de reproducir repetidamente un SystemSoundID (para siempre)? Editar: Terminé usando esto para reproducir el SystemSoundID siempre:

// Utilities.h 
#import <Foundation/Foundation.h> 
#import <AudioToolbox/AudioServices.h> 


static void soundCompleted(SystemSoundID soundID, void *myself); 

@interface Utilities : NSObject { 

} 

+ (SystemSoundID)createSystemSoundIDFromFile:(NSString *)fileName ofType:(NSString *)type; 
+ (void)playAndRepeatSystemSoundID:(SystemSoundID)soundID; 
+ (void)stopPlayingAndDisposeSystemSoundID; 

@end 


// Utilities.m 
#import "Utilities.h" 


static BOOL play; 

static void soundCompleted(SystemSoundID soundID, void *interval) { 
    if(play) { 
     [NSThread sleepForTimeInterval:(NSTimeInterval)interval]; 
     AudioServicesPlaySystemSound(soundID); 
    } else { 
     AudioServicesRemoveSystemSoundCompletion(soundID); 
     AudioServicesDisposeSystemSoundID(soundID); 
    } 

} 

@implementation Utilities 

+ (SystemSoundID)createSystemSoundIDFromFile:(NSString *)fileName ofType:(NSString *)type { 
    NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:type]; 
    SystemSoundID soundID; 

    NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO]; 

    AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID); 
    return soundID; 
} 

+ (void)playAndRepeatSystemSoundID:(SystemSoundID)soundID interval:(NSTimeInterval)interval { 
    play = YES 
    AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, 
              soundCompleted, (void *)interval); 
    AudioServicesPlaySystemSound(soundID); 
} 

+ (void)stopPlayingAndDisposeSystemSoundID { 
    play = NO 
} 

@end 

parece funcionar bien .. Y para el sello parpadear Voy a usar un NSTimer supongo.

Respuesta

6

Un temporizador es más adecuado para un intervalo estrictamente definido. Perderá precisión si tiene su función se llama a sí misma con un retraso porque no es realmente sincronizado con un intervalo de tiempo. Siempre hay tiempo para ejecutar el método real, lo que interrumpe el intervalo.

Quédate con un NSTimer, diría yo.

1

Dado que su aplicación depende de la precisión del tiempo (es decir, debe ejecutarse una vez por segundo), el NSTimer sería mejor. El método en sí requiere tiempo para ejecutarse, y un NSTimer estaría bien con eso (siempre que su método tome menos de 1 segundo, si se llama cada segundo).

para reproducir repetidamente su sonido, se puede establecer una devolución de llamada terminación y reproducir el sonido allí:

SystemSoundID tickingSound; 

... 

AudioServicesAddSystemSoundCompletion(tickingSound, NULL, NULL, completionCallback, (void*) self); 

... 

static void completionCallback(SystemSoundID mySSID, void* myself) { 
    NSLog(@"completionCallback"); 

    // You can use this when/if you want to remove the completion callback 
    //AudioServicesRemoveSystemSoundCompletion(mySSID); 

    // myself is the object that called set the callback, because we set it up that way above 
    // Cast it to whatever object that is (e.g. MyViewController, in this case) 
    [(MyViewController *)myself playSound:mySSID]; 
} 
2

sólo para añadir un poco de las otras respuestas, en el caso de una llamada recursiva sería cuando la llamada puede tomar una cantidad de tiempo desconocida, digamos que está llamando a un servicio web repetidamente con pequeñas cantidades de datos hasta que haya terminado. Cada llamada puede tardar un tiempo desconocido, por lo que el código no hará nada hasta que la llamada web regrese, luego se enviará el siguiente lote hasta que no queden más datos por enviar y el código no se vuelva a llamar a sí mismo.

+0

Esto es útil para contrastar los dos métodos. –

Cuestiones relacionadas