webentwicklung-frage-antwort-db.com.de

Warten in Objective-C und Swift

Ich möchte den Text meines UILabel nach 2 Sekunden ändern.

Ich habe versucht, den Text meines UILabel auf "A text" zu setzen, und habe sleep(2) verwendet und schließlich den Text auf "Another text" geändert .

Aber sleep(2) friert nur die App ein und "Another text" wird eingestellt, ohne "A text" für 2 Sekunden anzuzeigen.

Wie kann ich "Ein Text" für 2 Sekunden anzeigen und dann "Ein anderer Text" anzeigen?

43
jylee

Sie können verwenden

[self performSelector:@selector(changeText:) withObject:text afterDelay:2.0];

oder wenn Sie es regelmäßig anzeigen möchten, überprüfen Sie die Klasse NSTimer .

40
Michał Zygar

Ich weiß, ich bin zu spät zu dieser Party. Aber ich habe festgestellt, dass die Leute den Threadschlaf nicht erwähnt haben. Wenn Sie GCD verwenden, um diese Funktion aufzurufen. Sie können verwenden:

[NSThread sleepForTimeInterval:2.0f];   

um den Thread um 2 Sekunden zu verzögern.

[self changeText: @"A text"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //Here your non-main thread.
        [NSThread sleepForTimeInterval:2.0f];   
        dispatch_async(dispatch_get_main_queue(), ^{
            //Here you returns to main thread.
            [self changeText: @"Another text"];
        });
    });

Edit 2 (Feb. 2015):

Ich denke, der NSTimer ist eine großartige Lösung. Meine Lösung bietet nur eine weitere Option, um das Ziel von NSTimer zu erreichen.

Bitte lesen Sie: Wie verwende ich NSTimer?

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

In der Klasse benötigen Sie diese Methode:

- (void) doSomethingWhenTimeIsUp:(NSTimer*)t {

        // YES! Do something here!!

}

Edit 3 (Mai 2016):

In Swift 2.0 können Sie folgendermaßen vorgehen:

 NSTimer.scheduledTimerWithTimeInterval(2.0, 
                                         target: self, 
                                       selector: "doSomethingWhenTimeIsUp:", 
                                       userInfo: nil, 
                                        repeats: false)

Es erstellt eine NSTimer-Entität und fügt den Timer automatisch der NSRunLoop hinzu, die dem NSThread zugeordnet ist, in dem der Timer erstellt wird.

Bearbeiten 4 (Jun 2016):

In Swift 2.2 können Sie select folgendermaßen aufrufen:

#selector(doSomethingWhenTimeIsUp(_:))

Es ist also so etwas wie:

  NSTimer.scheduledTimerWithTimeInterval(2.0,
                                      target: self,
                                      selector: #selector(doSomethingWhenTimeIsUp()),
                                      userInfo: nil,
                                      repeats: false)

Edit 5 (Okt 2016):

In Swift 3 können Sie select folgendermaßen aufrufen:

#selector(doSomethingWhenTimeIsUp)

Es ist also so etwas wie:

        Timer.scheduledTimer(timeInterval: 2.0,
                             target: self,
                             selector:#selector(doSomethingWhenTimeIsUp),
                             userInfo: nil,
                             repeats: false)

Dann sollte die Funktion so aussehen:

        @objc private func doSomethingWhenTimeIsUp(){
        // Do something when time is up
        }

Edit 6 (Mai 2018):

In Swift 4 können wir wie folgt vorgehen.

    let delaySeconds = 2.0
    DispatchQueue.main.asyncAfter(deadline: .now() + delaySeconds) {
        doSomethingWhenTimeIsUp()
    }  

Dann sollte die Funktion so aussehen:

    private func doSomethingWhenTimeIsUp(){
        // Do something when time is up
        }
80
Yi Jiang

Grand Central Dispatch verfügt über eine Hilfsfunktion dispatch_after(), mit der Operationen nach einer Verzögerung ausgeführt werden können, die sehr hilfreich sein kann. Sie können die Wartezeit vor der Ausführung und die Instanz dispatch_queue_t Angeben, auf der sie ausgeführt werden soll. Sie können dispatch_get_main_queue() verwenden, um auf dem Hauptthread (UI) auszuführen.

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    // do something
});

In Swift kann das obige Beispiel wie folgt geschrieben werden:

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    // do something
}
28
Mick MacCallum

Sie können NSTimer wie folgt verwenden:

[NSTimer scheduledTimerWithTimeInterval:0.5 
                                 target:self 
                               selector:@selector(updateLabel:) 
                               userInfo:nil 
                                repeats:YES];

Definieren Sie eine andere Methode updateLabel und führen Sie dort die Aktualisierung durch. Definieren Sie Ihr Zeitintervall, um es Ihren Bedürfnissen anzupassen ...

Wenn Sie außerdem repeats auf YES setzen, wird sichergestellt, dass dieser Selektor alle 0,5 Sekunden ausgeführt wird (in diesem Fall).

12

Sie können dies mit einem Timer erreichen, z.

   NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(eventToFire:) userInfo:nil repeats:YES]; // Fire every 4 seconds.

   ...

   - (void)eventToFire:(NSTimer*)timer {
      // Do Something
   }
5
George Johnston

Dies liegt daran, dass die Ansicht erst am Ende des Runloops aktualisiert wird. Verwenden Sie NSTimer, um eine bestimmte Zeit zum Aktualisieren der Ansicht festzulegen, anstatt den Ruhezustand zu verwenden.

2
Dave

Sie müssen einen Timer verwenden. Wenn Sie den Energiesparmodus verwenden, wird das gesamte Programm angehalten. Überprüfen Sie NSTimer

2
Pepe

Die folgende Methode ist gut.

Sie können Ihre ersetzen

schlaf (1);

mit

dispatch_semaphore_t semaphore = dispatch_semaphore_create (0); dispatch_semaphore_wait (Semaphore, dispatch_time (DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC));

0
JateXu