2010-02-09 6 views
22

Gibt es eine direktere Möglichkeit, in Cocoa eine bestimmte Zeit zu warten, als das, was ich unten erwähnt habe?Warten auf eine bestimmte Dauer in Cocoa

- (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]; 
} 

einfach klar zu sein, gibt es kein funktionelles Problem mit diesem Code - mein einziges Rindfleisch ist ein stilistischen ein. In meinem Fall ist der Fluss einfach genug, dass es funktioniert, aber versuche es einzukapseln oder setze einige Bedingungen ein und die Dinge könnten hässlich werden. Es ist schon quälende Art von mir, dass ich nicht einen Weg zu warten und dann wieder auf den gleichen Punkt in Code wie dieses (fiktives) Beispiel finden könnte:

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

Antwort

61

Es gibt

usleep(1000000); 

und

[NSThread sleepForTimeInterval:1.0f]; 

von denen beide schlafen für 1 Sekunde.

+8

und beide aus den Thread blockiert etwas anderes zu tun. schlecht, wenn es in der Hauptsache U.I. Faden. – pestilence669

+3

Wahr. Wenn die Benutzeroberfläche in diesem Zeitraum reagieren soll, ist der in der Frage vorgeschlagene Ansatz, ein NSTimer-Feuern (wie von Ihnen vorgeschlagen) oder ein Hintergrund-Thread, der diese Verzögerung durchführt, besser. –

+0

Danke - darüber habe ich mich gewundert, wäre wahrscheinlich darüber gestolpert, wenn "schlafen" eines der vielen Synonyme für "warten" gewesen wäre, nach denen ich gesucht hatte. Danke auch an Pestilence für die Vorbehalte, wenn * diese * nicht benutzt werden. –

2

Sie wollen wahrscheinlich ein NSTimer und es müssen verwenden sende eine "doStuffAfterWaiting" Nachricht als Callback. Jede Art von "Schlaf" blockiert den Thread, bis er aufwacht. Wenn es in Ihrer U.I. thread, wird Ihre App "tot" angezeigt. Auch wenn das nicht der Fall ist, ist es eine schlechte Form. Der Callback-Ansatz wird die CPU freigeben, um andere Aufgaben auszuführen, bis das angegebene Zeitintervall erreicht ist.

Diese doc hat Anwendungsbeispiele und erläutert die Unterschiede auf, wie & wo Sie Ihren Timer erstellen können.

Natürlich performSelector: afterDelay: macht das gleiche.

3

Ich bin mir 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 recht einfach sein, einen wenig Wrapper wie performBlock:afterDelay: zu schreiben, die genau das tut, was Sie wollen, ohne die Notwendigkeit, den gesamten Thread zu schlafen. Wäre in der Tat ein nützliches kleines Stück Code.

Mike Ash hat written about an approach like this on his blog:

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

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

+2

Es blockiert den Thread. Wenn es im Wesentlichen aufgerufen wird, töten Sie effektiv die Run-Schleife und die App wird "tot" – pestilence669

+3

Dann rufen Sie nicht von der Haupt – Charlie

10

Hier ist der NSTimer Weg, es zu tun. Es ist vielleicht sogar hässlicher als die Methode, die Sie verwenden, aber es ermöglicht wiederholte Ereignisse, 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 einfach aufhängt und es unempfindlich macht.

+1

Ich denke, Sie meinen 'NSTimer', nicht' NSThread'. –

+7

"' Sie möchten etwas wie usleep() vermeiden, das Ihre App einfach aufhängt und es nicht mehr reagiert. "" Ziemlich sicher, das ist nur wahr, wenn Sie 'usleep' aus dem Hauptthread aufgerufen haben. – chown

0

Wenn Sie nicht eine asynchrone Lösung dagegen, hier gehen Sie:

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