web-dev-qa-db-de.com

In Cocoa wird eine bestimmte Zeit lang gewartet

Gibt es einen einfacheren Weg, um auf eine bestimmte Zeit in Cocoa zu warten, als ich es unten beschrieben habe?

- (void) buttonPressed {
    [self makeSomeChanges];

    // give the user some visual feedback and wait a bit so he can see it
    [self displayThoseChangesToTheUser];
    [self performSelector:@selector(buttonPressedPart2:) withObject:nil afterDelay:0.35];
}

- (void) buttonPressedPart2: (id)unused {
    [self automaticallyReturnToPreviousView];
}

Nur um klar zu sein, gibt es keine funktionell Problem mit diesem Code - mein einziges Rindfleisch ist ein stilistisch ein. In meinem Fall ist der Fluss so einfach, dass er funktioniert, aber versuchen Sie, ihn einzukapseln oder einige Konditionale zu werfen, und Dinge könnten hässlich werden. Es war irgendwie quälend auf mich, dass ich keinen Weg finden konnte, um zu warten und dann im Code wie diesem (fiktiven) Beispiel zu demselben Punkt zurückzukehren:

- (void) buttonPressed {
    [self doStuff];
    [UIMagicUnicorn waitForDuration:0.35];
    [self doStuffAfterWaiting];
}
26

Es gibt 

usleep(1000000);

und 

[NSThread sleepForTimeInterval:1.0f];

beide werden für 1 Sekunde schlafen.

66
Brad Larson

Hier ist der NSTimer-Weg. Es ist vielleicht noch hässlicher als die Methode, die Sie verwenden, aber es ermöglicht das Wiederholen von Ereignissen, also bevorzuge ich es.

[NSTimer scheduledTimerWithTimeInterval:0.5f 
                                 target:self
                               selector: @selector(doSomething:) 
                               userInfo:nil
                                repeats:NO];

Sie möchten etwas wie usleep () vermeiden, das Ihre App nur aufhängt und dazu führt, dass sie sich nicht mehr anspricht.

10
Jason Moore

Ich bin nicht sicher, ob es (noch) nicht existiert, aber mit Blöcken in 10.6 (oder PLBlocks in 10.5 und auf dem iPhone) sollte es ziemlich einfach sein, einen kleinen Wrapper wie performBlock:afterDelay: zu schreiben, der genau das macht, was Sie wollen die Notwendigkeit, den gesamten Thread zu schlafen. Wäre in der Tat ein nützliches kleines Stück Code.

Mike Ash hat über einen Ansatz wie diesen in seinem Blog geschrieben :

NSString *something = ...;
RunAfterDelay(0, ^{
    NSLog(@"%@", something);
    [self doWorkWithSomething: something];
});
3
Ole Begemann

Sie möchten wahrscheinlich ein NSTimer verwenden und eine "doStuffAfterWaiting" -Meldung als Rückruf senden. Jede Art von "sleep" blockiert den Thread, bis er aufwacht. Wenn es in Ihrer U.I. Thread, wird Ihre App "tot" erscheinen. Auch wenn das nicht der Fall ist, ist es eine schlechte Form. Der Callback-Ansatz befreit die CPU für andere Aufgaben, bis das angegebene Zeitintervall erreicht ist.

Dieses doc enthält Verwendungsbeispiele und erläutert die Unterschiede, wie und wo Sie Ihren Timer erstellen.

Natürlich gibt performSelector: afterDelay: dasselbe vor.

2
pestilence669

Was ist los mit einer einfachen usleep? Ich meine, abgesehen von "Kakao-Reinheit" ist es immer noch viel kürzer als andere Lösungen :)

2
F'x

TA Dah !

Etwas informativer, verweist der Link auf NSThread sleepForTimeInterval:

Dies wurde tatsächlich gestohlen von: Was ist das Äquivalent von Javas Thread.sleep () in Objective-C/Cocoa?

0
Malaxeur

Wenn Sie sich nicht für eine asynchrone Lösung interessieren, gehen Sie hier:

[[NSOperationQueue currentQueue] addOperationWithBlock:^{
    [self doStuffAfterWaiting];
}];
0