All UITableCells rendered at once... why?

Posted by Greg on Stack Overflow See other posts from Stack Overflow or by Greg
Published on 2010-06-07T17:06:37Z Indexed on 2010/06/07 17:32 UTC
Read the original article Hit count: 268

Filed under:
|
|

I'm extremely confused by the proper behavior of UITableView cell rendering. Here's the situation:

I have a list of 250 items that are loading into a table view, each with an image. To optimize the image download, I followed along with Apple's LazyTableImages sample code... pretty much following it exactly. Really good system... for reference, here's the cell renderer within the Apple sample code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // customize the appearance of table view cells
    //
    static NSString *CellIdentifier = @"LazyTableCell";
    static NSString *PlaceholderCellIdentifier = @"PlaceholderCell";

    // add a placeholder cell while waiting on table data
    int nodeCount = [self.entries count];

    if (nodeCount == 0 && indexPath.row == 0)
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
        if (cell == nil)
        {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                           reuseIdentifier:PlaceholderCellIdentifier] autorelease];   
            cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }

        cell.detailTextLabel.text = @"Loading…";

        return cell;
    }

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                       reuseIdentifier:CellIdentifier] autorelease];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

    // Leave cells empty if there's no data yet
    if (nodeCount > 0)
    {
        // Set up the cell...
        AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];

        cell.textLabel.text = appRecord.appName;
        cell.detailTextLabel.text = appRecord.artist;

        // Only load cached images; defer new downloads until scrolling ends
        if (!appRecord.appIcon)
        {
            if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
            {
                [self startIconDownload:appRecord forIndexPath:indexPath];
            }
            // if a download is deferred or in progress, return a placeholder image
            cell.imageView.image = [UIImage imageNamed:@"Placeholder.png"];                
        }
        else
        {
           cell.imageView.image = appRecord.appIcon;
        }

    }

    return cell;
}

So – my implementation of Apple's LazyTableImages system has one crucial flaw: it starts all downloads for all images immediately. Now, if I remove this line:

//[self startIconDownload:appRecord forIndexPath:indexPath];

Then the system behaves exactly like you would expect: new images load as their placeholders scroll into view. However, the initial view cells do not automatically load their images without that prompt in the cell renderer. So, I have a problem: with the prompt in the cell renderer, all images load at once. Without the prompt, the initial view doesn't load. Now, this works fine in Apple sample code, which got me wondering what was going on with mine. It's almost like it was building all cells up front rather than just the 8 or so that would appear within the display. So, I got looking into it, and this is indeed the case... my table is building 250 unique cells! I didn't think the UITableView worked like this, I guess I thought it only built as many items as were needed to populate the table. Is this the case, or is it correct that it would build all 250 cells up front?

Also – related question: I've tried to compare my implementation against the Apple LazyTableImages sample, but have discovered that NSLog appears to be disabled within the Apple sample code (which makes direct behavior comparisons extremely difficult). Is that just a simple publish setting somewhere, or has Apple somehow locked down their samples so that you can't log output at runtime?

Thanks!

© Stack Overflow or respective owner

Related posts about iphone

Related posts about objective-c