2011-10-21 9 views
8

Tengo un UITableView con celdas personalizadas. Cargo imágenes de forma asíncrona usando Grand Central Dispatch. Todo funciona bien, pero cuando me desplazo hacia abajo, las imágenes cargadas anteriormente se muestran hasta que se descarga la nueva imagen. Aquí está mi código:GCD UITableVer imágenes de carga asíncrona, las celdas incorrectas se cargan hasta que se descargue la nueva imagen

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. P.S. Reutilizo las celdas

Respuesta

18

En lugar de la captura de la célula necesita para capturar la ruta del índice, a continuación, obtener la célula hacia atrás usando:

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

De esta manera, si la celda está ahora fuera de la pantalla que obtendrá nula espalda y la imagen no se establecerá en la celda incorrecta.

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

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"]]; 
} 
+0

gracias por su respuesta ... pero, ¿podría proporcionar algún código de ejemplo? – blackhawk4152

+0

Actualizado mi respuesta – hypercrypt

+0

gracias, hombre! justo lo que quería – blackhawk4152

2

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

2

No UITableViewCell definir - (void) prepareForReuse para ese propósito? Anularlo y borrar su imagenVer allí.

+0

Según la [documentación] (http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableViewCell/prepareForReuse) no debes tocar el contenido dentro de prepareForReuse. Debe restablecer el contenido en cellForRowAtIndexPath en su lugar. –

Cuestiones relacionadas