Frage

einen Methodenaufruf zu wiederholen (oder eine Nachricht senden, ich denke, der richtige Begriff ist) alle x Sekunden, ist es besser, einen NSTimer (NSTimer des scheduledTimerWithTimeInterval zu verwenden: Ziel: Selektor: userinfo: Wiederholungen: ) oder das Verfahren rekursiv selbst am Ende nennen zu haben (mit perform: withobject: afterDelay)? Letztere kein Objekt verwenden, aber vielleicht ist es weniger klar / lesbar? Auch nur, um Ihnen eine Vorstellung davon, was ich tue, es ist nur eine Ansicht mit einem Etikett, das bis 12:00 Uhr Mitternacht herunterzählt, und wenn es auf 0 wird, wird die Zeit (00.00.00) blinken und immer einen Piepton spielen.

Danke.

Edit: auch, was wäre der beste Weg, um wiederholt eine SystemSoundID (für immer) zu spielen? Edit: Ich landete mit dieser die SystemSoundID spielen für immer:

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

Es scheint gut zu funktionieren .. Und für das Label zu blinken werde ich ein NSTimer Ich denke, verwendet werden.

War es hilfreich?

Lösung

Ein Zeitgeber ist besser geeignet für ein streng definierten Intervall. Sie Genauigkeit verlieren, wenn Sie Ihre Funktion selbst mit einer Verzögerung nennen, weil es nicht wirklich synchronisiert zu einem Zeitintervall. Es gibt immer die Zeit, das eigentliche Verfahren selbst als auch laufen, die über das Intervall stellt.

Stick mit einem NSTimer, würde ich sagen.

Andere Tipps

Nur ein bisschen zu den anderen Antworten hinzuzufügen, wäre der Fall für einen rekursiven Aufruf, wenn der Anruf eine unbekannte Menge an Zeit in Anspruch nehmen könnte - sagen Sie einen Web-Service immer wieder mit kleinen Datenmengen fordern, bis Sie fertig sind. Jeder Anruf kann eine unbekannte Menge an Zeit in Anspruch nehmen, so dass Sie den Code nichts zu tun haben, bis die Web-Aufruf zurückkehrt, dann wird die nächste Charge bleibt, bis keine Daten mehr gesendet werden gesendet und der Code nicht selbst wieder aufrufen.

Da Ihre Anwendung auf Zeitgenauigkeit hängt (das heißt es einmal pro Sekunde ausführen muss), würde die NSTimer besser sein. Es dauert einige Zeit für die Methode selbst ausführen, und ein NSTimer wäre schön, mit, dass (solange Ihre Methode weniger als 1 Sekunde dauert, wenn es jede Sekunde aufgerufen wird).

wiederholt, um Ihren Sound zu spielen, können Sie einen Abschluss Rückruf einstellen und den Ton wiederzugeben es:

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];
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top