10
votes

iPhone Dev - Effecselector: withObject: AfterDelay ou Nstimer?

Pour répéter un appel de méthode (ou message de message, je suppose que le terme approprié est) tous les x em> secondes, est-il préférable d'utiliser un NSTIMER (NSTIMER'S SchedulgueredTimerwithInterval: Cible: Sélecteur: UserInfo: Répéter: ) ou pour que la méthode s'appelle récursivement s'appelle à la fin (à l'aide de Professelector: withObject: AfterDelay)? Ce dernier n'utilise pas d'objet, mais peut-être que c'est moins clair / lisible? En outre, juste pour vous donner une idée de ce que je fais, c'est juste une vue avec une étiquette qui compte jusqu'à 12h00 minuit, et quand il arrive à 0, il clignotera le temps (00:00:00) Et jouez un bip sonore pour toujours.

Merci. P>

EDIT: En outre, quelle serait la meilleure façon de jouer à plusieurs reprises un système Systemound (Forever)? EDIT: J'ai fini par utiliser ceci pour lire le SystemSound pour toujours: p>

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


0 commentaires

3 Réponses :


6
votes

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

Stick avec un NSTIMER, je dirais.


0 commentaires

1
votes

Étant donné que votre application dépend de la précision du temps (c'est-à-dire qu'il doit être exécuté une fois par seconde), le NSTIMER serait mieux. Il faut un certain temps pour la méthode elle-même à exécuter, et un NSTIMER irait bien avec cela (tant que votre méthode prend moins de 1 seconde, si elle s'appelle chaque seconde).

Pour jouer à plusieurs reprises votre son, vous pouvez définir Un rappel d'achèvement et rejouez le son: P>

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];
}


0 commentaires

2
votes

Juste pour ajouter un peu aux autres réponses, le cas d'un appel récursif serait lorsque l'appel peut prendre une quantité de temps inconnue - disons que vous appelez un service Web à plusieurs reprises avec de petites quantités de données jusqu'à ce que vous soyez terminé. Chaque appel peut prendre un peu de temps inconnu afin que le code ne fasse rien que lorsque l'appel Web ne renvoie que le lot suivant est envoyé jusqu'à ce que plus aucune donnée reste envoyée et que le code ne s'appelle plus.


1 commentaires

Ceci est utile pour contraster les deux méthodes.