web-dev-qa-db-fra.com

En attente d'une durée déterminée en cacao

Existe-t-il un moyen plus simple d’attendre une période de temps spécifique dans Cocoa que ce que j’ai proposé ci-dessous?

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

Juste pour être clair, il n'y a pas fonctionnel problème avec ce code - mon seul boeuf est un stylistique un. Dans mon cas, le flux est assez simple pour que cela fonctionne, mais essayez de l'encapsuler ou d'ajouter des conditions et les choses pourraient tourner mal. Cela me faisait penser que je ne pouvais pas trouver un moyen d'attendre avant de revenir au même point dans le code, comme dans l'exemple (fictif) suivant:

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

Il y a 

usleep(1000000);

et 

[NSThread sleepForTimeInterval:1.0f];

qui vont dormir pendant 1 seconde.

66
Brad Larson

Voici la façon de faire NSTimer. C'est peut-être encore plus laid que la méthode que vous utilisez, mais cela permet de répéter des événements, donc je le préfère.

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

Vous voulez éviter quelque chose comme usleep () qui accrocherait simplement votre application et la rendrait insensible.

10
Jason Moore

Je ne sais pas s'il existe (encore), mais avec des blocs dans 10.6 (ou PLBlocks dans 10.5 et sur l'iPhone), il devrait être assez facile d'écrire un petit emballage comme performBlock:afterDelay: qui fait exactement ce que vous voulez sans la nécessité de dormir tout le fil. Serait un petit morceau de code utile en effet.

Mike Ash a écrit sur une telle approche sur son blog :

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

Vous voudrez probablement utiliser un NSTimer et lui faire envoyer un message "doStuffAfterWaiting" comme rappel. Tout type de "sommeil" bloquera le fil jusqu'à son réveil. Si c'est dans votre U.I. fil, cela fera apparaître votre application "morte". Même si ce n'est pas le cas, sa forme est mauvaise. L'approche de rappel permettra au processeur de faire d'autres tâches jusqu'à ce que votre intervalle de temps spécifié soit atteint.

Ce doc contient des exemples dutilisation et discute des différences entre comment et où créer votre minuterie.

Bien sûr, performSelector: afterDelay: fait la même chose.

2
pestilence669

Quel est le problème avec un simple usleep? Je veux dire, sauf pour des raisons de "pureté du cacao", c'est toujours beaucoup plus court que d'autres solutions :)

2
F'x

Et voilà !

Un peu plus informatif, le lien pointe vers NSThread sleepForTimeInterval:

Cela a été volé à: Quel est l'équivalent de Thread.sleep () de Java dans Objective-C/Cocoa?

0
Malaxeur

Si une solution asynchrone ne vous dérange pas, voici ce que vous faites:

[[NSOperationQueue currentQueue] addOperationWithBlock:^{
    [self doStuffAfterWaiting];
}];
0
Julian F. Weinert