Cancelar NSTimers asociados con UITableViewCells cuando salen de la pantalla.

Implemento una UITableView de células UIImageView , cada una de las cuales se actualiza periódicamente cada 5 segundos a través de NSTimer . Cada image se carga desde un server en el hilo de background, y desde ese hilo de background también actualizo la interfaz de usuario, mostrando la nueva image, llamando a performSelectorOnMainThread . Hasta aquí todo bien.

El problema que noté es que el número de subprocesss aumenta con el time y la interfaz de usuario se vuelve no receptiva. Por lo tanto, quiero invalidar NSTimer si una celda se apaga de la pantalla. ¿Qué methods de delegación en UITableView debo usar para hacer esto de manera eficiente?

La razón por la que asocio un NSTimer con cada celda porque no quiero que la transición de la image ocurra al mismo time para todas las celdas. ¿Hay algún otro método para hacer esto por cierto? Por ejemplo, ¿es posible usar solo un único NSTimer ?

(No puedo usar SDWebImage porque mi requisito es mostrar un set de imágenes en bucle cargado desde un server)

// en MyViewController.m

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... NSTimer* timer=[NSTimer scheduledTimerWithTimeInterval:ANIMATION_SCHEDULED_AT_TIME_INTERVAL target:self selector:@selector(updateImageInBackground:) userInfo:cell.imageView repeats:YES]; ... } - (void) updateImageInBackground:(NSTimer*)aTimer { [self performSelectorInBackground:@selector(updateImage:) withObject:[aTimer userInfo]]; } - (void) updateImage:(AnimatedImageView*)animatedImageView { @autoreleasepool { [animatedImageView refresh]; } } 

// En AnimatedImageView.m

  -(void)refresh { if(self.currentIndex>=self.urls.count) self.currentIndex=0; ASIHTTPRequest *request=[[ASIHTTPRequest alloc] initWithURL:[self.urls objectAtIndex:self.currentIndex]]; [request startSynchronous]; UIImage *image = [UIImage imageWithData:[request responseData]]; // How do I cancel this operation if I know that a user performs a scrolling action, therefore departing from this cell. [self performSelectorOnMainThread:@selector(performTransition:) withObject:image waitUntilDone:YES]; } -(void)performTransition:(UIImage*)anImage { [UIView transitionWithView:self duration:1.0 options:(UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction) animations:^{ self.image=anImage; currentIndex++; } completion:^(BOOL finished) { }]; } 

Si administra correctamente la memory y elimina las celdas reutilizables, puede subclass UITableViewCell y anular su método - prepareForReuse para detener el timer.

Además, como @lnfaziger señala, si desea detener el timer inmediatamente cuando se quita la celda de la vista de tabla, también puede anular su willMoveToSuperview: y / o didMoveToSuperview: y comprobar si su parámetro de superview es nil – si es Es decir, la celda se está eliminando, por lo que puede detener el cronómetro.

willMoveToSuperview: y / o didMoveToSuperview: no funciona en ios 6.0

desde ios 6.0 tiene el siguiente método de UITableViewDelegate

 - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 

Utilice este método para detectar cuándo se quita una celda de una vista de tabla, en lugar de supervisar la vista misma para ver cuándo aparece o desaparece.