objective-c ios multithreading uikit grand-central-dispatch

objective c - ¿Cuál es la diferencia entre performSelectorOnMainThread y dispatch_async en la cola principal?



objective-c ios (3)

Estaba teniendo problemas para modificar una vista dentro de un hilo. Traté de agregar una subvista, pero tardó alrededor de 6 segundos en mostrarse. Finalmente lo hice funcionar, pero no sé exactamente cómo. Entonces me preguntaba por qué funcionó y cuál es la diferencia entre los siguientes métodos:

//this worked -added the view instantly dispatch_async(dispatch_get_main_queue(), ^{ //some UI methods ej [view addSubview: otherView]; } //this took around 6 or more seconds to display [viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:NO]; //Also didnt work: NSNotification methods - took also around 6 seconds to display //the observer was in the viewController I wanted to modify //paired to a method to add a subview. [[NSNotificationCenter defaultCenter] postNotificationName: @"notification-identifier" object:object];

Para referencia, esto fue llamado dentro de este Manejador de Completación de la clase de ACAccountStore.

accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) { if(granted) { //my methods were here } }

Editar: Cuando digo que no funcionó, quise decir que tardó unos 6 segundos en mostrar la vista que agregué.


¿Has PerformSelectorOnMainThread el PerformSelectorOnMainThread con waitUntilDone=YES

P.ej:

Código:

[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];

Creo que eso podría resolver el problema de por qué el PerformSelectorOnMainThread tarda tanto tiempo en responder.


De forma predeterminada, -performSelectorOnMainThread:withObject:waitUntilDone: solo programa el selector para que se ejecute en el modo de ciclo de ejecución predeterminado. Si el ciclo de ejecución está en otro modo (por ejemplo, el modo de seguimiento), no se ejecutará hasta que el ciclo de ejecución vuelva al modo predeterminado. Puede -performSelectorOnMainThread:withObject:waitUntilDone:modes: esto con la variante -performSelectorOnMainThread:withObject:waitUntilDone:modes: (pasando todos los modos en los que desea que se ejecute).

Por otro lado, dispatch_async(dispatch_get_main_queue(), ^{ ... }) ejecutará el bloque tan pronto como el ciclo de ejecución principal devuelva el flujo de control al bucle de evento. No le importan los modos. Entonces, si no quieres preocuparte por los modos, dispatch_async() puede ser la mejor manera de hacerlo.


Es probable porque performSelectorOnMainThread:withObject:waitUntilDone: cola el mensaje con los modos de ciclo de ejecución comunes. De acuerdo con la Guía de programación de concurrencia de Apple , la cola principal entrelazará las tareas en cola con otros eventos del ciclo de ejecución de la aplicación. Por lo tanto, si hay otros eventos que procesar en la cola de eventos, los bloques en cola en la cola de distribución se pueden ejecutar primero, aunque se enviaron más tarde.

Este artículo es una excelente explicación para performSelectorOnMainThread vs. dispatch_async , que también responde a la pregunta anterior.