wake-up-neo.com

Wie benutze ich NSTimer?

Wie verwende ich ein NSTimer? Kann mir jemand schrittweise Anweisungen geben?

345
lab12

Zunächst möchte ich Ihre Aufmerksamkeit auf die Cocoa/CF-Dokumentation lenken (die immer eine gute erste Anlaufstelle ist). Die Apple -Dokumente haben oben in jedem Referenzartikel einen Abschnitt mit der Bezeichnung "Begleithandbücher", in dem Handbücher für das zu dokumentierende Thema aufgeführt sind (sofern vorhanden). Zum Beispiel listet die Dokumentation mit NSTimer zwei Hilfslinien auf:

Für Ihre Situation ist der Artikel Timer-Programmierthemen wahrscheinlich am nützlichsten, während Threading-Themen zwar mit der zu dokumentierenden Klasse zusammenhängen, jedoch nicht am unmittelbarsten. Wenn Sie sich den Artikel Timer Programming Topics ansehen, besteht er aus zwei Teilen:

  • Timer
  • Timer verwenden

Bei Artikeln, die dieses Format annehmen, gibt es häufig eine Übersicht über die Klasse und deren Verwendungszweck und anschließend einen Beispielcode für die Verwendung , in diesem Fall im Abschnitt " Verwenden von Timern ". Es gibt Abschnitte zu "Erstellen und Planen eines Timers", "Anhalten eines Timers" und "Speicherverwaltung". In diesem Artikel können Sie einen geplanten, sich nicht wiederholenden Timer wie folgt erstellen:

[NSTimer scheduledTimerWithTimeInterval:2.0
    target:self
    selector:@selector(targetMethod:)
    userInfo:nil
    repeats:NO];

Dadurch wird ein Timer erstellt, der nach 2,0 Sekunden ausgelöst wird und targetMethod: für self mit einem Argument aufruft, das ein Zeiger auf die Instanz NSTimer ist.

Wenn Sie sich dann die Methode genauer ansehen möchten, können Sie auf die Dokumentation zurückgreifen, um weitere Informationen zu erhalten. Es gibt jedoch auch Erläuterungen zum Code.

Wenn Sie einen Timer stoppen möchten, der sich wiederholt (oder einen nicht wiederholenden Timer stoppen möchten, bevor er ausgelöst wird), müssen Sie einen Zeiger auf die erstellte Instanz NSTimer beibehalten. In vielen Fällen muss es sich um eine Instanzvariable handeln, damit Sie in einer anderen Methode darauf verweisen können. Sie können dann invalidate für die Instanz NSTimer aufrufen:

[myTimer invalidate];
myTimer = nil;

Es hat sich auch bewährt, die Instanzvariable nil auszugeben (wenn Ihre Methode, die den Timer ungültig macht, beispielsweise mehrmals aufgerufen wird und die Instanzvariable nicht auf nil gesetzt wurde und die Zuordnung der Instanz NSTimer aufgehoben wurde, wird eine Ausnahme ausgelöst). .

Beachten Sie auch den Punkt zur Speicherverwaltung am Ende des Artikels:

Da die Ausführungsschleife den Zeitgeber verwaltet, ist es aus Sicht der Speicherverwaltung normalerweise nicht erforderlich, einen Verweis auf einen Zeitgeber zu speichern, nachdem Sie ihn geplant haben . Da der Timer als Argument übergeben wird, wenn Sie seine Methode als Selektor angeben , können Sie einen sich wiederholenden Timer bei Bedarf innerhalb dieser Methode ungültig machen . In vielen Situationen möchten Sie jedoch auch die Möglichkeit haben, den Timer zu deaktivieren - möglicherweise noch bevor er gestartet wird. In diesem Fall müssen Sie einen Verweis auf den Timer behalten, damit Sie ihm bei Bedarf eine ungültige Nachricht senden können . Wenn Sie einen außerplanmäßigen Zeitgeber erstellen (siehe „Außerplanmäßige Zeitgeber“), müssen Sie einen starken Verweis auf den Zeitgeber beibehalten (in einer Umgebung mit Referenzzählung müssen Sie ihn beibehalten), damit die Zuordnung nicht aufgehoben wird, bevor Sie ihn verwenden.

617
Alex Rozanski

es gibt verschiedene Möglichkeiten, einen Timer zu verwenden:

1) geplanter Timer & mit Selektor

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];
  • wenn Sie die Anzahl der Wiederholungen auf NEIN setzen, wartet der Timer 2 Sekunden, bevor der Selektor ausgeführt wird. Danach stoppt er.
  • bei Wiederholung: JA, der Timer startet sofort und ruft den Selektor alle 2 Sekunden erneut auf.
  • um den Timer zu stoppen, rufen Sie die Methode -invalidate des Timers auf: [t invalidate];

Anstatt einen Timer zu verwenden, der sich nicht wiederholt und den Selektor nach einem bestimmten Intervall aufruft, können Sie eine einfache Anweisung wie die folgende verwenden:

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

dies hat den gleichen Effekt wie der obige Beispielcode. Wenn Sie den Selektor jedoch jedes n-te Mal aufrufen möchten, verwenden Sie den Timer mit Wiederholungen: JA;

2) selbstauslöser

NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
NSTimer *t = [[NSTimer alloc] initWithFireDate: d
                              interval: 1
                              target: self
                              selector:@selector(onTick:)
                              userInfo:nil repeats:YES];

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:t forMode: NSDefaultRunLoopMode];
[t release];
  • dadurch wird ein Timer erstellt, der an einem von Ihnen festgelegten Datum startet (in diesem Fall nach einer Minute) und sich jede Sekunde wiederholt

3) außerplanmäßiger Timer und Aufruf

NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(onTick:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:@selector(onTick:)];

NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
                      invocation:inv 
                      repeats:YES];

und danach starten Sie den Timer manuell, wann immer Sie dies benötigen:

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];



Und als Hinweis sieht die onTick: -Methode so aus:

-(void)onTick:(NSTimer *)timer {
   //do smth
}
332
Woofy

Etwas wie das:

NSTimer *timer;

    timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
                     target: self
                     selector: @selector(handleTimer:)
                     userInfo: nil
                     repeats: YES];
59
ennuikiller
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];

-(void)timerCalled
{
     NSLog(@"Timer Called");
     // Your Code
}
5
Mohit
#import "MyViewController.h"

@interface MyViewController ()

@property (strong, nonatomic) NSTimer *timer;

@end

@implementation MyViewController

double timerInterval = 1.0f;

- (NSTimer *) timer {
    if (!_timer) {
        _timer = [NSTimer timerWithTimeInterval:timerInterval target:self selector:@selector(onTick:) userInfo:nil repeats:YES];
    }
    return _timer;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

-(void)onTick:(NSTimer*)timer
{
    NSLog(@"Tick...");
}

@end
5
Dan

Bei den Antworten fehlt eine bestimmte Uhrzeit. Der Timer ist hier auf die nächste Stunde eingestellt:

NSCalendarUnit allUnits = NSCalendarUnitYear   | NSCalendarUnitMonth |
                          NSCalendarUnitDay    | NSCalendarUnitHour  |
                          NSCalendarUnitMinute | NSCalendarUnitSecond;

NSCalendar *calendar = [[ NSCalendar alloc]  
                          initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *weekdayComponents = [calendar components: allUnits 
                                                  fromDate: [ NSDate date ] ];

[ weekdayComponents setHour: weekdayComponents.hour + 1 ];
[ weekdayComponents setMinute: 0 ];
[ weekdayComponents setSecond: 0 ];

NSDate *nextTime = [ calendar dateFromComponents: weekdayComponents ];

refreshTimer = [[ NSTimer alloc ] initWithFireDate: nextTime
                                          interval: 0.0
                                            target: self
                                          selector: @selector( doRefresh )
                                          userInfo: nil repeats: NO ];

[[NSRunLoop currentRunLoop] addTimer: refreshTimer forMode: NSDefaultRunLoopMode];

Ersetzen Sie "doRefresh" natürlich durch die gewünschte Methode Ihrer Klasse

versuchen Sie, das Kalenderobjekt einmal zu erstellen und die allUnits aus Effizienzgründen statisch zu machen.

das Hinzufügen einer Stunde-Komponente funktioniert einwandfrei, es ist kein Mitternachtstest erforderlich ( link )

2
gjpc