views:

60

answers:

4

Hello,

Is there any message I can override called when a Table Cell goes away (on scrolling the table)?

I think it should be something like dealoc.

I'm asking this because I have below situation: I have a table with many cells (100+) and each of this cell contains a ImageView. For loading the image (from a URL) I'm using NSOperationQueue/NSInvocationOperation. The problem appears when user is scrolling the table before the image is completely loaded: because I'm reusing the cells the image is displayed in wrong cell.

To avoid this I'm thinking to use "cancelAllOperations" of NSOperationQueue object when the cell goes away.

Note: I've tried but is not working if I call this message on "prepareForReuse".

+1  A: 

Why not keeping the images in your table data source - the array that holds all the data for the table?

This way you won't have to load these images once again when scrolling back and it will solve your problem...

Michael Kessler
Hi,Thanks for your tip. I'll take this approach.I'll just have to find a way to avoid overflowing the memory. Any other tips about this will be welcomed, thanks.
I don't think this will cause you memory problems. What are the sizes of the images?
Michael Kessler
Unfortunately, is it various. But we can assume will not exceed 150Kb each.
You can also track which ones are visible and if you get a memory warning, release all the ones that are not currently visible.
progrmr
A: 

If there were, it would be in the UITableViewDelegate class reference: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITableViewDelegate

The only thing they have is willDisplayCell which lets you do last minute adjustments BEFORE the cell appears. They don't have anything for when it disappears, but you could probably figure that out since there are only a certain number of cells on the screen at a time for a given cell height.

So if one is appearing and for a cell height of 80 for instance (in portrait mode so 480px screen height), then you can say that the one 6 cells away is about to disappear (6 cells * 80 pixels = 480). There are a couple other things to consider like which way you are scrolling, but you get the general idea.

Example Code: You should also look at lazy table loading via Apple's sample code http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Introduction/Intro.html

iWasRobbed
+1  A: 

You can subclass UITableViewCell (or any UIView) and override willMoveToWindow:. It is called whenever the cell appears (or scrolls off screen).

When it goes out of the window the parameter will be nil:

- (void)willMoveToWindow:(UIWindow *)newWindow
{
    [super willMoveToWindow:newWindow];

    if (newWindow==nil) {
            // Cell is no longer in window
    }
}
progrmr
A: 

Hi! I had the same issue and got some nice feedback in the developer forum. Quinn - The Eskimo from Apple:

As an aside, cancelling a network small transfer because something has scrolled off the screen is probably a performance negative. For small transfers, it's usually more efficient to let it run to completion (and cache the results in case they're needed in the future). This is because of the way that NSURLConnection manages HTTP connection reuse. If you cancel a transfer, NSURLConnection has to either a) drop the underlying HTTP connection on the floor, which means it can't be reused, or b) continue reading and just junk the data. Neither of this is the best use of resources.

Share and Enjoy -- Quinn "The Eskimo!"

So, I'm not cancelling all the ImageDownload Operation, but rather only start them, when the user stops scrolling. Up to then only a placeholder is shown:

- (void)scrollViewWillBeginDragging:(UITableView *) tableView
{
    self.dragging = TRUE;
}

- (void) scrollViewDidEndDragging: (UITableView *) tableView willDecelerate: (BOOL) decelerate
{
    if(!decelerate && self.dragging)
        [self loadThumbsForVisibleCells];    
    else 
        self.dragging = FALSE; 

}

- (void) scrollViewDidEndDecelerating: (UITableView *) tableView
{
    [self loadThumbsForVisibleCells];
}

Hope this helps!

W.Gerick