2009-09-29 16 views
10

Per ripetere una chiamata di metodo (o invio messaggio, suppongo che il termine appropriato sia) ogni x secondi, è meglio utilizzare un NSTimer (NSTimer's scheduledTimerWithTimeInterval: target: selector: userInfo: ripetizioni :) o per avere il metodo chiamarsi ricorsivamente alla fine (usando performSelector: withObject: afterDelay)? Quest'ultimo non usa un oggetto, ma forse è meno chiaro/leggibile? Inoltre, solo per darti un'idea di quello che sto facendo, è solo una vista con un'etichetta che conta fino alle 12:00 di mezzanotte, e quando arriva a 0, lampeggerà il tempo (00:00:00) e suonare un segnale acustico per sempre.iPhone dev - performSelector: withObject: afterDelay o NSTimer?

Grazie.

Modifica: anche, quale sarebbe il modo migliore per riprodurre ripetutamente un SystemSoundID (per sempre)? Edit: ho finito per usare questo per riprodurre lo SystemSoundID per sempre:

// 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 

sembra funzionare bene .. E per l'etichetta lampeggiante userò un NSTimer immagino.

risposta

6

Un timer è più adatto a un intervallo strettamente definito. Perderai la precisione se hai la funzione chiamata stessa con un ritardo perché non è realmente sincronizzata a un intervallo di tempo. C'è sempre il tempo necessario per eseguire il metodo vero e proprio che mette fuori intervallo.

Stick con un NSTimer, direi.

1

Poiché l'applicazione dipende dall'accuratezza del tempo (ovvero deve essere eseguita una volta al secondo), NSTimer sarebbe migliore. Ci vuole del tempo per l'esecuzione del metodo stesso, e un NSTimer andrebbe bene con questo (a patto che il tuo metodo impieghi meno di 1 secondo, se viene chiamato ogni secondo).

Per riprodurre più volte il suono, è possibile impostare una richiamata di completamento e riprodurre il suono c'è:

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

solo per aggiungere un po 'per le altre risposte, il caso di una chiamata ricorsiva sarebbe quando la chiamata potrebbe impiegare una quantità di tempo sconosciuta - ad esempio, stai chiamando ripetutamente un servizio Web con piccole quantità di dati finché non hai finito. Ogni chiamata può richiedere un po 'di tempo sconosciuto, in modo che il codice non faccia nulla fino a quando la chiamata web non ritorna, quindi il batch successivo viene inviato fino a quando non vengono più inviati dati e il codice non si chiama di nuovo.

+0

Questo è utile per contrastare i due metodi. –

Problemi correlati