J'essaie d'afficher une feuille sur une fenêtre contenant une seule barre de progression, pour montrer la progression de certaines fonctions longues exécutées de manière asynchrone à l'aide de Grand Central Dispatch. Je l'ai presque obtenu, mais je n'arrive pas à faire apparaître la feuille comme étant nette, probablement parce que je n'ai pas utilisé runModalForWindow:
ou similaire.Comment afficher correctement une feuille de "progression" en utilisant Grand Central Dispatch pour traiter quelque chose?
C'est à peu près ce que je fais en ce moment, il se produit à la suite d'un bouton pression sur la fenêtre principale:
// Prepare sheet and show it...
[NSApp beginSheet:progressSheet modalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
[progressSheet makeKeyAndOrderFront:self];
[progressBar setIndeterminate:NO];
[progressBar setDoubleValue:0.f];
[progressBar startAnimation:self];
// Start computation using GCD...
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (int i = 0; i < 1000; i ++) {
// Do some large computation here
// ...
// Update the progress bar which is in the sheet:
dispatch_async(dispatch_get_main_queue(), ^{
[progressBar setDoubleValue:(double)i];
});
}
// Calculation finished, remove sheet on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[progressBar setIndeterminate:YES];
[NSApp endSheet:progressSheet];
[progressSheet orderOut:self];
});
});
Cela fonctionne, sauf la fenêtre principale est toujours mise au point, la la feuille n'est pas mise au point et la barre de progression ne s'anime pas (sauf si j'utilise setUsesThreadedAnimation:YES
dessus).
Le problème que je crois avoir est que je ne suis pas sûr de savoir comment exécuter la feuille modalement sans bloquer le thread principal avant de lancer le calcul asynchrone?
L'exécution modale de la feuille pour la fenêtre ne devrait pas bloquer le thread principal (sinon rien après l'exécution de votre bit '-beginSheet:' au début de la méthode). J'utilise quelque chose de presque identique à celui-ci (feuille modale présentée comme vous le faites, avec une barre de progression dessus) dans mon application ici, et il se met à jour très bien à partir d'un bloc GCD exécuté en arrière-plan. Les contrôles sur la fenêtre à partir desquels la feuille glisse sont grisés, indiquant que la fenêtre a perdu le focus sur la feuille, ce qui semble normal. Pourrait-il y avoir quelque chose d'autre qui met en file d'attente beaucoup d'actions sur le thread principal? –
@BradLarson La seule autre chose que je pouvais penser qui pourrait causer des problèmes était un 'dispatch_apply' dans le cadre du calcul principal, mais le remplacer par une boucle standard ne faisait aucune différence. Sinon, il n'y a pratiquement rien d'autre qui tourne sur le thread principal. Je peux toujours interagir principalement avec les commandes de la fenêtre principale, derrière la feuille, et elles apparaissent toujours en surbrillance (c'est-à-dire qu'elles ne sont pas grisées). Une zone de texte sur la fenêtre principale, par exemple, pendant l'affichage de la feuille, apparaît avec une bague de mise au point et je peux toujours y saisir du texte (bien que je ne puisse pas sélectionner de texte avec la souris). – Robert