UITableView reloadData demorando demasiado time

Estoy usando TBXML + HTTP para get datos XML de un website. Lo que quiero hacer es rellenar un UITableView con los datos procesados. He creado un NSMutableArray que contiene todas las inputs y, en lo que va, todo funciona bien. El problema es cuando, después de recuperar con éxito los datos del server y almacenarlos en la matriz, bash actualizar la tabla para mostrar los datos, utilizando reloadData .

Se tarda unos 5 segundos en completar la tabla con 20 filas. La parte extraña es que la obtención está sucediendo muy rápido, por lo que los datos están disponibles de inmediato. No entiendo lo que lleva tanto time. Aquí hay alguna información del logging:

 2012-03-17 18:46:01.045 MakeMyApp[4571:207] numberOfSectionsInTableView: 1 2012-03-17 18:46:01.047 MakeMyApp[4571:207] numberOfRowsInSection: 0 2012-03-17 18:46:01.244 MakeMyApp[4571:1f03] numberOfSectionsInTableView: 1 2012-03-17 18:46:01.245 MakeMyApp[4571:1f03] numberOfRowsInSection: 20 2012-03-17 18:46:01.245 MakeMyApp[4571:1f03] Ok, I'm done. 20 objects in the array. 2012-03-17 18:46:01.246 MakeMyApp[4571:1f03] Finished XML processing. 2012-03-17 18:46:06.197 MakeMyApp[4571:1f03] cellForRowAtIndexPath: 

Como puede ver, dispara el par numberOfSectionsInTableView: / numberOfRowsInSection: dos veces: la primera es cuando la vista se carga, la segunda es cuando hago [self.tableView reloadData];

Verá que, en less de un segundo, la matriz se completa con los 20 objects y todo el trabajo que procesa el XML se realiza. ¿Cómo es cellForRowAtIndexPath: se cellForRowAtIndexPath: solo 5 segundos después?

Estas son algunas partes del código que pueden ayudar a encontrar el problema:

 - (void)createRequestFromXMLElement:(TBXMLElement *)element { // Let's extract all the information of the request int requestId = [[TBXML valueOfAttributeNamed:@"i" forElement:element] intValue]; TBXMLElement *descriptionElement = [TBXML childElementNamed:@"d" parentElement:element]; NSString *description = [TBXML textForElement:descriptionElement]; TBXMLElement *statusElement = [TBXML childElementNamed:@"s" parentElement:element]; int status = [[TBXML textForElement:statusElement] intValue]; TBXMLElement *votesCountElement = [TBXML childElementNamed:@"v" parentElement:element]; int votesCount = [[TBXML textForElement:votesCountElement] intValue]; // Creating the Request custom object Request *request = [[Request alloc] init]; request.requestId = requestId; request.description = description; request.status = status; request.votes_count = votesCount; [requestsArray addObject:request]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { appListCell *cell = (appListCell *)[tableView dequeueReusableCellWithIdentifier:@"appListCell"]; Request *request = [requestsArray objectAtIndex:indexPath.row]; cell.appIdLabel.text = [NSString stringWithFormat:@"#%d", request.requestId]; cell.appTextLabel.text = request.description; cell.appVotesLabel.text = [NSString stringWithFormat:@"%d votes", request.votes_count]; return cell; } 

¡Muchas gracias!

EDITAR:

 - (void)traverseXMLAppRequests:(TBXMLElement *)element { int requestCount = 0; TBXMLElement *requestElement = element->firstChild; // Do we have elements inside <re>? if ((requestElement = (element->firstChild))) { while (requestElement) { [self createRequestFromXMLElement:requestElement]; requestCount++; requestElement = [TBXML nextSiblingNamed:@"r" searchFromElement:requestElement]; } } [self.tableView reloadData]; NSLog(@"Ok, I'm done. %d objects in the array.", [requestsArray count]); } 

EDIT 2: He intentado get la información de solo 1 fila, en lugar de 20, y la demora es exactamente la misma.

Sé que esta es una pregunta muy antigua, pero acabo de encontrar el mismo problema y creo que podría saber la causa. Puede ayudar a alguien que tropiece con esta misma pregunta …

Sospecho que su llamada de reloadData está sucediendo en un hilo de background en lugar del hilo principal. Lo que usted describe es el efecto exacto de esto: el código funciona, pero hay una larga demora (5-10 segundos) en la actualización de la interfaz de usuario.

Intente cambiar la llamada de reloadData a:

 dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); 

Estás llamando a reloadData en un hilo distinto de mainThread

Asegúrate de volver a cargar los tableView tu tableView en el hilo principal como en el siguiente:

OBJ-C:

 [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 

Swift 3:

 DispatchQueue.main.async { self.tableView.reloadData() } 

Donde hace:

 - (void)createRequestFromXMLElement:(TBXMLElement *)element 

¿te llaman? Suena como si estuviera haciendo 20 requestes web para get ese contenido de file. Eso definitivamente haría las cosas más lentas (en lugar de hacer una request para get todo el file XML y analizarlo localmente).

¿Puedes publicar tu código de VC completo?