2013-07-11 13 views
9

che sto programmando un'applicazione che fa uso di richieste web asincrone utilizzando NSURLConnection, quindi non ho più thread in esecuzione. Per garantire che la logica principale del mio app accade su un filo, sto facendo un uso pesante di performSelectorOnMainThread:waitUntilDone:. A volte, però, sto eseguendo questo argomento sul thread principale, che ha stuzzicato la mia curiosità.Se performSelectorOnMainThread: waitUntilDone: viene chiamato dal thread principale, quando sarà eseguito?

Se performSelectorOnMainThread:waitUntilDone: viene chiamato mentre nel thread principale? Funziona allo stesso modo di performSelector:? Che cosa succede se waitUntilDone: è YES? Cosa succede se è NO?

EDIT: ho trovato che quando waitUntilDone: è YES, il selettore viene eseguita (quasi) immediatamente, ma non posso capire quando viene eseguito se waitUntilDone: è NO.

+0

Ho scoperto che quando 'waitUntilDone:' è 'YES', il selettore viene eseguito (quasi) immediatamente, ma non riesco a capire quando viene eseguito se' waitUntilDone: 'è' NO'. – Jumhyn

+0

Il debugger non aiuta qui? Basta cercare quando viene generato un nuovo thread. –

+0

@Cole, 'performSelector' ** OnMainThread: ** non sta per creare un thread, specialmente quando è chiamato _from_ il thread principale. –

risposta

13
performSelectorOnMainThread:withObject:waitUntilDone: 

è un metodo per consegnare un messaggio sul main thread del vostro application. Qui il valore boolean nel parametro waitUntilDone: specifica che si desidera bloccare il proprio main thread per l'esecuzione specificato o meno selector.

per esempio -

se scritto queste due linee-

[self performSelectorOnMainThread:@selector(print) withObject:nil waitUntilDone:YES]; 

NSLog(@"Hello iPhone"); 

e questo è il metodo di stampa -

- (void) print 
{ 
    NSLog(@"Hello World"); 
} 

allora si otterrà questo o/p

Hello World 
Hello iPhone 

così è abeti t mettere in pausa l'esecuzione del main thread e stampa "Ciao Mondo" e poi eseguire thread principale di nuovo e di stampa "Ciao iPhone", perché è stato specificato YES in waitUntilDone:

ma se è stato specificato NO in waitUntilDone: allora stamperà come questo -

Hello iPhone 
Hello World 

indica chiaramente che ha messo la richiesta di eseguire il specificato selector in un queue e come ottiene OS sua main thread gratuito è eseguita voi richiesta.

Calling performSelectorOnMainThread:withObject:waitUntilDone: sia da main thread o un secondary thread non fa alcuna differenza nella sua esecuzione, dipende da ciò che si è specificato nel waitUntilDone:

per ulteriori informazioni -

NSObject Class Reference

+0

@saabdip +1 per una bella spiegazione. – iLearner

+1

Sono decisamente pignolo, ma hai torto in "Se si specifica" NO ", quindi stamperà" Hello iPhone \ nHelloWorld "". Infatti, e dato che il sito di chiamata non è in esecuzione sul thread principale, l'ordine delle due uscite è * non * determinabile. Altrimenti, se il sito di chiamata viene eseguito sul thread principale, il thread principale non verrà bloccato, invece se _waitUntilDone_ è 'YES' il selettore verrà immediatamente eseguito. ;) La tua ultima affermazione è troppo vaga. – CouchDeveloper

1
If the current thread is also the main thread, and you pass YES, 
the message is performed immediately, otherwise the perform is 
queued to run the next time through the run loop. 

Se SÌ, può essere eseguito prima dei ritorni performSelectorOnMainThread:withObject:waitUntilDone:.

ho trovato che quando waitUntilDone: è SI, viene eseguito il selettore (quasi) immediatamente, ma non posso capire quando viene eseguito se waitUntilDone: è NO.

Il bit sul ciclo di esecuzione: il thread principale ha un ciclo di esecuzione. Questo più o meno impedisce ad un thread di uscire. Un ciclo di esecuzione gestisce un elenco di cose da fare. Quando il suo lavoro è completo, sospende l'esecuzione di quel thread per un po 'di tempo. Poi si sveglia dopo e vede se ha del lavoro da fare.

La quantità di lavoro può variare notevolmente (ad esempio può fare un disegno molto pesante o file i/o tra il momento in cui si sveglia e il punto in cui viene eseguito il selettore. Pertanto, non è un buon strumento per un timing preciso, ma dovrebbe essere sufficiente per sapere come funziona e come le implementazioni aggiunge il lavoro per il ciclo corsa

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

1

Se waitUntilDone:.. è sI agisce come una chiamata di funzione immediata

Se waitUntilDone : è NO, quindi mette in coda la chiamata insieme alle chiamate di tutti gli altri thread.

Questo metodo accoda il messaggio sul circuito corsa del filo principale usando i loop di esecuzione comuni modi, cioè le modalità associate con i NSRunLoopCommonModes costanti. Come parte della normale elaborazione del ciclo di esecuzione , il thread principale rimuove il messaggio (supponendo che sia in esecuzione in una delle modalità di ciclo di esecuzione comuni) e invochi il metodo desiderato .

Come indicato sopra, le cose come disegno e I/O hanno la priorità su qualsiasi cosa nelle code. Una volta che il thread principale ottiene il tempo per il servizio in coda nel prossimo ciclo degli eventi, ci sono un paio di altri dettagli che non sono così semplici come contare al primo in prima uscita:

1) dispatch_async() ignora le modalità .

2) Le varianti performSelector con un argomento specifico della modalità - il rilevamento eventi, ad esempio - può avere la precedenza su quelle con l'argomento delle modalità comuni predefinite in un ciclo in esecuzione in quella specifica modalità.

Come regola generale, se si desidera comportamenti di temporizzazione prevedibili, è necessario utilizzare le funzioni di invio GCD di basso livello che non tengono conto di considerazioni di livello superiore come le modalità del ciclo di esecuzione.

Problemi correlati