multithreading asynchronous background grand-central-dispatch performselector

multithreading - comparación GCD vs. performSelectorInBackground: dispatch_async no en segundo plano



asynchronous grand-central-dispatch (1)

Grand Central Dispatch es excelente y reduce la cantidad de código, pero ¿por qué no puedo ejecutar algo en un hilo de fondo?
He hecho una aplicación de muestra para mostrar a qué me refiero (ninguno de los trabajos comentados):

- (IBAction)performSel { [self performSelectorInBackground:@selector(doStuff) withObject:nil]; [NSThread sleepForTimeInterval:3]; [[self.view.subviews lastObject] removeFromSuperview]; } - (IBAction)gcd { dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) { //dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) { //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { //dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { //dispatch_async(dispatch_get_main_queue(), ^(void) { //dispatch_sync(dispatch_get_main_queue(), ^(void) { [self doStuff]; // only for readability, will move the code on success }); [NSThread sleepForTimeInterval:3]; [[self.view.subviews lastObject] removeFromSuperview]; } - (void)doStuff { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; UIView *abortingView = [[UIView alloc]initWithFrame: self.view.bounds]; abortingView.backgroundColor = [UIColor whiteColor]; abortingView.alpha = 0.7; [self.view insertSubview:abortingView atIndex:10]; [abortingView release]; [pool drain]; }

el [NSThread sleepForTimeInterval:3]; es simular una funcionalidad de IU predeterminada. Por ejemplo, si alguien está cambiando de una vista de navegación a otra.
Simplemente copie el código en una nueva aplicación basada en vista, cree dos botones y conéctelos.


Las clases de UIKit deben usarse solo desde el hilo principal de una aplicación. (Desde iOS4, dibujar en un contexto de gráficos es seguro para subprocesos). No puede usar cosas de UIKit en una cadena de fondo.

Por lo tanto, solo puede usar dispatch_async (dispatch_get_main_queue (), block) en esta situación.

dispatch_async(dispatch_get_main_queue(), ^(void) {

Invocará el bloque en el hilo principal en el runloop del hilo principal.

dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {

Invocará el bloque en un hilo de fondo. No puede usarlo porque quiere usar UIKit en el bloque. Y tenga cuidado dispatch_async (dispatch_queue_create ( , podría causar pérdida de memoria, debe liberar la cola serie creada por dispatch_queue_create).

dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) { dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {

dispatch_sync espera hasta que el bloque esté listo.

dispatch_sync(dispatch_get_main_queue(), ^(void) {

Causa DEADLOCK.