Sto provando a visualizzare un foglio su una finestra contenente una singola barra di avanzamento, per mostrare lo stato di avanzamento di alcune funzioni lunghe in modo asincrono utilizzando Grand Central Dispatch. L'ho quasi capito, ma non riesco a mettere a fuoco il foglio, probabilmente perché non ho usato runModalForWindow:
o simili.Come visualizzare correttamente un foglio "avanzamento" durante l'uso di Grand Central Dispatch per elaborare qualcosa?
Questo è approssimativamente quello che sto facendo in questo momento, accade come conseguenza di un pulsante nella finestra 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];
});
});
Questo funziona, parte la finestra principale è ancora a fuoco, la il foglio non è a fuoco e la barra di avanzamento non si anima (a meno che non utilizzi lo setUsesThreadedAnimation:YES
su di esso).
Il problema che penso di avere è che non sono sicuro di come eseguire il foglio in modo modulare senza bloccare il thread principale prima di avviare il calcolo asincrono?
L'esecuzione modale del foglio per la finestra non dovrebbe bloccare il thread principale (altrimenti nulla dopo il '-beginSheet:' bit all'inizio del metodo verrebbe eseguito). Io uso qualcosa di quasi identico a questo (il foglio modale presentato come fai tu, con una barra di avanzamento) nella mia applicazione qui, e si aggiorna bene da un blocco GCD eseguito in background. I controlli sulla finestra in cui il foglio scorre verso il basso sono in grigio, a indicare che la finestra ha perso il focus sul foglio, quindi anche questo sembra normale. Potrebbe esserci qualcos'altro che fa la coda di molte azioni sul thread principale? –
@BradLarson L'unica altra cosa che potevo pensare che potesse causare problemi era un 'dispatch_apply' come parte del calcolo principale, ma sostituirlo con un ciclo standard non faceva alcuna differenza. Altrimenti, non c'è praticamente nient'altro in esecuzione sul thread principale. Posso ancora interagire principalmente con i controlli sulla finestra principale, dietro il foglio, e appaiono ancora a fuoco (cioè, non disattivati). Ad esempio, una finestra di testo sulla finestra principale, mentre il foglio viene visualizzato, appare con un anello di messa a fuoco e posso ancora inserire del testo (anche se non posso selezionare il testo con il mouse). – Robert