2012-05-10 16 views
5

Tengo UITableView con cierto contenido, que se carga en asincrónico modo. Cuando el usuario gira el dispositivo, necesito hacer [tableView reloadData] en el método -willRotateToInterfaceOrientation. ReloadData funciona de manera asíncrona en mi caso.¿Cómo hacer que MainThread espere hasta que se realice alguna acción asíncrona?

Entiendo que reloadData funciona en el hilo principal, pero dispara cellForRowAtIndexPath, que funciona de manera asíncrona en mi caso.

Así que la pregunta es cómo hacer que el hilo principal espere hasta UITableView's reloadData termina.

Respuesta

2

Si llama a reloadData desde willRotateToInterfaceOrientation, se invoca en el hilo principal. De hecho, las UIViews NO son seguras para hilos y solo deberían tratarse desde el hilo principal (en caso de que por alguna razón alguien tenga la idea de llamar a reloadData desde otro hilo).

Creo que hay confusión con respecto a "asincrónico" como un término. Las devoluciones de llamada asincrónicas para delegados de IU como willRotateToInterfaceOrientation se invocan en el hilo principal. Ser asincrónico no significa necesariamente un hilo diferente (aunque ejecutar asíncronamente "en paralelo").

Recomendaría leer en la documentación de Apple para NSRunLoop. Es una parte integral de la forma en que se ejecutan las aplicaciones de iOS y es una tarea obligada para los programadores de aplicaciones.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

+0

Entiendo que se llama a reloadData en el hilo principal. Pero realodData llama a cellForRowAtIndexPath ... y este método necesita cargar algunos datos asincrónicos. –

+0

Veo, por lo que no está esperando que reloadData se complete, pero las tareas asíncronas que reloadData se apagan se completan. ¿Podrías modificar tu pregunta para reflejar esto? NSRunLoop sigue siendo lo que quieres, aunque no entiendo por qué quieres mantener el hilo principal como rehén mientras cargas de datos asíncronas. – NSProgrammer

+0

Necesito un hilo principal para esperar reloadData, porque esto hará que la animación de rotación sea agradable. –

3

Es posible utilizar CFRunLoopRun a hacer su espera hilo principal hasta que se vuelve a cargar los datos UITableView. Después de volver a cargar los datos, llame al CFRunLoopStop pasando el resultado de CFRunLoopGetMain como parámetro.

+0

Gracias, veo que esto no es tan fácil de hacer leyendo la documentación. Trataré de entender. –

2

Tendrá que cargar los datos de su tabla en segundo plano, luego llame al método reloadData de UITableView.

Puede usar GCD para enviar fácilmente su función de carga de forma asíncrona a una cola en segundo plano. Cuando la tarea haya finalizado, haga que el hilo del trabajador envíe de nuevo al hilo principal un bloque que llame al [tableView reloadData]. He aquí cómo:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 

    ... 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 

    // load your table data here 
    [self loadMyTableData]; 

    // when done dispatch back to the main queue to load the table 
    dispatch_queue_t mainQueue = dispatch_get_main_queue(); 
    dispatch_async(mainQueue, ^{ 

     [self.tableView reloadData]; 
     }); 
    }); 
    ... 
} 
+0

Para hacer [self loadMyTableData]; Necesito cambiar la mitad del código para almacenar los datos y luego pasarlo a mis celdas de vista subutilizadas y su contenido –

Cuestiones relacionadas