Imágenes de carga asíncrona GCD UITableView, las células incorrectas se cargan hasta que se descargue la nueva image

Tengo una UITableView con celdas personalizadas. Cargo imágenes de manera asíncrona usando Grand Central Dispatch. Todo funciona bien, pero cuando me desploop hacia abajo, se muestran imágenes previamente cargadas hasta que se descargue la nueva image. Aquí está mi código:

if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; NSURL *imageURL=[NSURL URLWithString:u]; NSData *image=[NSData dataWithContentsOfURL:imageURL]; [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; dispatch_sync(dispatch_get_main_queue(), ^{ cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; [cell setNeedsLayout]; NSLog(@"Download"); }); }); } else { NSLog(@"cache"); cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; } 

Cualquier sugerencia apreciada. PS reutilizo las celdas

En lugar de capturar la celda, necesita capturar la ruta del índice, luego recupere la celda usando:

 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

De esta manera, si la celda está ahora fuera de la pantalla, volverá a cero y la image no se establecerá en la celda incorrecta.

La otra cosa que debe agregar después de su dispatch_async() es una cell.imageView.image=somePlaceholderImage .

P.ej:

 if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; NSURL *imageURL=[NSURL URLWithString:u]; NSData *image=[NSData dataWithContentsOfURL:imageURL]; [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; dispatch_sync(dispatch_get_main_queue(), ^{ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; [cell setNeedsLayout]; NSLog(@"Download"); }); }); cell.imageView.image=[UIImage imageNamed:@"placeholder"]; } else { NSLog(@"cache"); cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; } 

En su - (void)tableView:(UITableView *)aTableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { Necesita borrar la image o restablecerla a su ruleta. Como las filas de vista de tabla se reutilizan, este es el comportamiento que verá.

¿UITableViewCell no define – (void) prepareForReuse para ese propósito? Reemplace y borre su imageView allí.