2009-09-29 16 views
10

Aby powtórzyć wywołanie metody (lub wysłać wiadomość, myślę, że odpowiedni termin jest) co sekund x, czy lepiej użyć NSTimer (NSTimer's zaplanowaneTimerWithTimeInterval: cel: selector: userInfo: Powtarza :) lub mieć metodę rekursywnie wywołuje się na końcu (używając performSelector: withObject: afterDelay)? Ten ostatni nie używa obiektu, ale może jest mniej czytelny/czytelny? Ponadto, aby dać ci wyobrażenie o tym, co robię, jest to tylko widok z etykietą, która odlicza do północy 00, a kiedy osiągnie 0, będzie migać czas (00:00:00) i odtwarzaj sygnał dźwiękowy na zawsze.iPhone dev - performSelector: withObject: afterDelay lub NSTimer?

Dzięki.

Edycja: także, jaki byłby najlepszy sposób na wielokrotne odtwarzanie SystemSoundID (na zawsze)? Edit: I skończyło się to grać SystemSoundID zawsze:

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

wydaje się działać dobrze .. I na etykiecie migającym będę używać NSTimer chyba.

Odpowiedz

6

Zegar jest bardziej dostosowany do ściśle określonego przedziału czasowego. Stracisz celność, jeśli masz wywołanie funkcji z opóźnieniem, ponieważ nie jest ono zsynchronizowane z przedziałem czasowym z. Zawsze jest czas, aby uruchomić samą metodę, która powoduje, że interwał się kończy.

Trzymam z NSTimerem, powiedziałbym.

1

Ponieważ twoja aplikacja zależy od dokładności czasu (tj. Musi być wykonywana raz na sekundę), NSTimer będzie lepszy. Wykonanie tej metody zajmuje trochę czasu, a NSTimer będzie z tym w porządku (o ile twoja metoda zajmuje mniej niż 1 sekundę, jeśli jest wywoływana co sekundę).

Aby wielokrotnie odtwarzać dźwięk, można ustawić wywołania zwrotnego zakończenia i odtwarzanie dźwięku tam:

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

Wystarczy dodać trochę do innych odpowiedzi, sprawa na rekurencyjne wywołanie byłoby, gdy połączenie może zająć nieznany czas - powiedzmy, że wielokrotnie wywołujesz usługę internetową z niewielkimi ilościami danych, dopóki nie skończysz. Każde wywołanie może zająć trochę nieznanego czasu, więc nie wykonasz żadnego kodu, dopóki połączenie internetowe nie powróci, a następna partia zostanie wysłana, dopóki nie będzie już żadnych danych do wysłania, a kod nie wywoła się ponownie.

+0

Jest to przydatne do kontrastowania obu metod. –

Powiązane problemy