2014-05-12 3 views
7

hinzugefügt habe ich einen Code-Schnipsel wie folgt aus:NSTimer nicht Wähler feuern, wenn sie mit scheduledTimerWithTimeInterval

m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds 
                 target:self 
                selector:@selector(activityIndicatorTimer:) 
                userInfo:nil 
                 repeats:NO]; 

Wenn ich es wie so der Wähler nennen wird nach den gegebenen timeOutInSeconds nicht gefeuert. Wenn ich es jedoch wie folgt ändere, wird der Selektor zweimal aufgerufen.

NSLog(@"Timer set"); 
m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds 
               target:self 
              selector:@selector(activityIndicatorTimer:) 
              userInfo:nil 
               repeats:NO]; 
[[NSRunLoop currentRunLoop] addTimer:m_timer forMode:NSRunLoopCommonModes]; 

Kann mir jemand einen Vorschlag machen, was ich wahrscheinlich falsch mache?

Ich bin mit XCode 5.1, und aufbauend auf 7.1.1 iPhone 4S

+4

Meine Vermutung ist Sie Laichen diesen Timer einen Hintergrund-Thread ohne Runloop aus (die meisten noch kein Konto haben) 'scheduledTimerWithTimeInterval' muss von einem Thread aufgerufen werden mit einem Runloop (normalerweise der Hauptthread). Um den Timer zu Runloop hinzuzufügen, wie Sie sind, sollten Sie stattdessen 'timerWithTimeInterval ...' verwenden. –

+0

Call '[m_timer Feuer]' nach der ersten Option –

+0

Danke David, ich glaube, Sie hatten Recht. Mit Ihrer Hilfe scheint es, dass ich das Problem gefunden habe. Wenn Sie dies als Antwort einreichen möchten, anstatt es zu kommentieren, kann ich es akzeptieren. – xceph

Antwort

29

Anruf dieser Timer in Hauptthread:

dispatch_async(dispatch_get_main_queue(), ^{ 
    m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds 
                target:self 
               selector:@selector(activityIndicatorTimer:) 
               userInfo:nil 
                repeats:NO]; 
}); 
1

Sie haben 3 Optionen bei der Erstellung Timer, wie Apple-Staaten in der doc:

  • Verwenden Sie die scheduledTimerWithTimeInterval:invocation:repeats: oder scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: Klasse Methode, um den Timer zu erstellen und in der aktuellen Laufschleife in den Standardmodus zu planen.
  • Verwenden der timerWithTimeInterval:invocation:repeats: oder timerWithTimeInterval:target:selector:userInfo:repeats: Klassenmethode das Timer-Objekt zu erzeugen, ohne es auf einer Laufschleifenplanung. (Nach es erstellen, müssen Sie den Timer auf eine Laufschleife hinzuzufügen manuell durch Aufruf des addTIMER: forMode. Methode des entsprechenden NSRunLoop Objekts)
  • die Timer zuweisen und initialisieren die initWithFireDate:interval:target:selector:userInfo:repeats: Methode. (nach der Erstellung zu können, müssen die Zeitgeber auf einen Laufschleife hinzuzufügen manuell durch die addTIMER Aufruf: forMode. Methode des entsprechenden NSRunLoop Objekt)

Die Methode Sie verwenden bereits disponiert die Timer auf der aktuellen Schleife und Sie sollten keine andere Zeit planen. Meiner Meinung nach ist das Problem anderswo, versuche (um es einfach zu machen), einen festen Wert anstelle von timeOutInSeconds zu setzen.
Auch die häufigste Art und Weise etwas nach einer bestimmten Verzögerung zu nennen (das soll nicht wiederholen) ist die Verwendung dispatch_after:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     //YOUR CODE 
    }); 

Wo die 2 ein beliebige Intervall (in diesem Fall 2 Sekunden).

+0

Das beantwortet die Frage nicht wirklich. –