2009-09-29 7 views
10

Pour répéter un appel de méthode (ou envoyer un message, je suppose que le terme approprié est) toutes les x secondes, est-il préférable d'utiliser un NSTimer (NSTimer's scheduledTimerWithTimeInterval: target: selector: userInfo: répète :) ou d'avoir la méthode s'appelle récursivement à la fin (en utilisant performSelector: withObject: afterDelay)? Ce dernier n'utilise pas d'objet, mais peut-être est-il moins clair/lisible? Aussi, juste pour vous donner une idée de ce que je fais, c'est juste une vue avec une étiquette qui compte jusqu'à minuit, et quand elle arrive à 0, elle clignotera l'heure (00:00:00) et jouez un bip sonore pour toujours.iPhone dev - performSelector: avecObjet: afterDelay ou NSTimer?

Merci.

Editer: aussi, quelle serait la meilleure façon de jouer à plusieurs reprises un SystemSoundID (pour toujours)? Edit: Je fini par utiliser ceci pour jouer le SystemSoundID pour toujours:

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

semble fonctionner très bien .. Et pour l'étiquette clignote, je vais utiliser un NSTimer je suppose.

Répondre

6

Une temporisation est plus adaptée à un intervalle strictement défini. Vous perdrez la précision si vous avez votre fonction s'appelle avec un retard parce que ce n'est pas vraiment synchronisé à un intervalle de temps. Il y a toujours le temps nécessaire pour exécuter la méthode elle-même, ce qui met l'intervalle à l'écart.

Stick avec un NSTimer, je dirais.

1

Étant donné que votre application dépend de la précision du temps (c'est-à-dire qu'elle doit s'exécuter une fois par seconde), le NSTimer serait meilleur. La méthode elle-même prend un certain temps à s'exécuter, et un NSTimer conviendrait parfaitement (tant que votre méthode prend moins d'une seconde, si elle est appelée toutes les secondes).

Pour jouer plusieurs fois à votre son, vous pouvez définir un rappel d'achèvement et de rejouer le son là:

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

Juste pour ajouter un peu aux autres réponses, le cas d'un appel récursif serait lorsque l'appel peut prendre un temps inconnu - disons que vous appelez un service Web à plusieurs reprises avec de petites quantités de données jusqu'à ce que vous ayez fini. Chaque appel peut prendre un certain temps afin que le code ne fasse rien jusqu'à ce que l'appel Web revienne, puis le lot suivant est envoyé jusqu'à ce qu'il ne reste plus de données à envoyer et que le code ne s'appelle plus.

+0

Ceci est utile pour contraster les deux méthodes. –

Questions connexes