Actualmente estoy intentando cargar una lista UITableView de Flickr Photo (cs193p iOS Stanford, asignación 5). Para evitar el evento de bloqueo de la interfaz de usuario, he diferido la descarga en miniatura de cada celda en una cola diferente (pero actualizo la interfaz de usuario en la cola principal). Este código no carga asíncronamente las imágenes, aunque sí agrega una miniatura cuando hago clic en la fila UITableViewCell. (ver capturas de pantalla a continuación). ¿Alguna idea de lo que estoy haciendo mal?Carga de imagen UITableViewCell asincrónica con GCD
PD: Ya he buscado en algunas otras preguntas de stackoverflow & ejemplo de LazyTableImages de Apple, pero sigo convencido de que esta es la forma más limpia de lograr el resultado deseado.
Gracias!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Photo List Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell
NSDictionary *photo = [self.photoList objectAtIndex:indexPath.row];
if (photo != nil) {
if ([[photo objectForKey:@"title"] length] > 0) {
cell.textLabel.text = [photo objectForKey:@"title"];
} else if ([[[photo objectForKey:@"description"] objectForKey:@"_content"] length] > 0) {
cell.textLabel.text = [[photo objectForKey:@"description"] objectForKey:@"_content"];
} else {
cell.textLabel.text = @"Unknown";
}
}
cell.imageView.image = [[UIImage alloc] initWithCIImage:nil];
// Fetch using GCD
dispatch_queue_t downloadThumbnailQueue = dispatch_queue_create("Get Photo Thumbnail", NULL);
dispatch_async(downloadThumbnailQueue, ^{
UIImage *image = [self getTopPlacePhotoThumbnail:photo];
dispatch_async(dispatch_get_main_queue(), ^{
if ([self.tableView.visibleCells containsObject:cell]) {
[cell.imageView setImage:image];
}
});
});
dispatch_release(downloadThumbnailQueue);
return cell;
}
Antes clic en una fila
Después de seleccionar la fila
ACTUALIZACIÓN: Para los interesados, este es el código final utilicé:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Photo List Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell
NSDictionary *photo = [self.photoList objectAtIndex:indexPath.row];
if (photo != nil) {
if ([[photo objectForKey:@"title"] length] > 0) {
cell.textLabel.text = [photo objectForKey:@"title"];
} else if ([[[photo objectForKey:@"description"] objectForKey:@"_content"] length] > 0) {
cell.textLabel.text = [[photo objectForKey:@"description"] objectForKey:@"_content"];
} else {
cell.textLabel.text = @"Unknown";
}
}
cell.imageView.image = [[UIImage alloc] initWithCIImage:nil];
// Fetch using GCD
dispatch_queue_t downloadThumbnailQueue = dispatch_queue_create("Get Photo Thumbnail", NULL);
dispatch_async(downloadThumbnailQueue, ^{
UIImage *image = [self getTopPlacePhotoThumbnail:photo];
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *cellToUpdate = [self.tableView cellForRowAtIndexPath:indexPath]; // create a copy of the cell to avoid keeping a strong pointer to "cell" since that one may have been reused by the time the block is ready to update it.
if (cellToUpdate != nil) {
[cellToUpdate.imageView setImage:image];
[cellToUpdate setNeedsLayout];
}
});
});
dispatch_release(downloadThumbnailQueue);
return cell;
}
Hey, esto es totalmente fuera de tema, pero se pregunta si el interior del bloque que usted envíe al hilo principal, en lugar de comprobar la igualdad objeto en la 'celda', compruebe si existe una celda en' indexPath' –
Acabo de probar esto: if ([self.tableView cellForRowAtIndexPath: indexPath]! = Nil) {... etc} y funciona igual de bien también. ¿Eso es lo que tenías en mente? – sybohy
Correcto, y no usa 'cell.imageView' directamente en su bloque, sino que toma la celda en' indexPath' y usa su vista de imagen. Creo que podría tener problemas con la reutilización de células si usa 'cell' directamente de la forma en que se encuentra dentro de su bloque de hilos principal. –