2012-07-06 13 views
7

so che è sicuro per disegnare su qualsiasi thread finché io chiamoQuesto thread di codice grafica è sicuro?

UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
UIGraphicsEndImageContext(); 

sullo stesso thread.

Prendere uno screenshot di una vista tramite questo metodo richiede circa 300 ms, che non è male, ma sono in una situazione difficile, quindi voglio farlo in una discussione in background.

Ecco quello che sto facendo:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
     [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
     UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
    }); 

L'unica cosa che qui in questione è il view, che si trova sul thread principale. È sicuro chiamare renderInContext su un view.layer da un thread in background? O in generale, è sicuro leggere solo un oggetto UIKit da un altro thread?

(E per favore non darmi il default "UIKit non è thread-safe" risposta. So già che. Questo qui è un caso particolare (e non venitemi a dire non ci sono casi speciali).)

(il codice qui sopra funziona bene, ma non sono sicuro se questo è solo una coincidenza.)

+0

Non credo che otterrete una risposta definitiva a questa domanda perché da nessuna parte nella documentazione Apple dichiarerà qualcosa di diverso da "UIKit non è thread-safe" (insieme alle eccezioni elencate). Ciò che otterrai sono opinioni ed esperienze di altre persone ma, come hai detto tu, il codice sopra funziona bene, ma chi dice che lo farà sempre e anche se qualcun altro ti dice che lo farà, vero? – Rog

+0

Le regole di threading si applicano anche alla modifica o alla lettura di un oggetto? – Snowman

+0

E se faccio una copia della vista prima, così sono sicuro che questo metodo sarebbe l'unico che ha accesso a questa nuova copia? – Snowman

risposta

7

Graphics core e core Animation essendo API di basso livello, sono generalmente thread-safe. Tuttavia, si applicano ancora le stesse regole sull'accesso: non è possibile accedere a qualsiasi lavoro da più di un thread contemporaneamente, altrimenti il ​​disegno non riuscirà e l'app si arresterà in modo anomalo. Sarei cauto (ma non spaventato) di UIImage, dato che gli oggetti UIKit non solo non sono sicuri, bensì basano le bombe a orologeria in sottofondo, e si immergeranno felicemente da una scogliera in Eccezione senza ragione. Tuttavia, poiché UIImage è solo un wrapper CGImage, di nuovo, la maggior parte del disegno è thread-safe.

+0

Quindi c'è un'alternativa intelligente per fare uno screenshot in background? Che ne dici di usare NSData nel thread bg e usarlo per costruire un'immagine sul thread principale? – Snowman

+0

Screenshot sullo sfondo? Non è possibile senza IOSurface, che Apple ora è abbastanza vividamente a conoscenza grazie a Display Recorder, tuttavia, se ciò non è importante, vedere [qui] (http://stackoverflow.com/questions/11090184/how-does-the- ios-app-display-recorder record-the-schermo-senza-using-privato-ap /). – CodaFi

+0

Non sullo sfondo background - background thread intendo .. – Snowman