Quick and easy image caching for UITableViews

PicSlide uses a table that lets you choose a picture to play with. For each picture it shows a thumbnail. When the thumbnails are loaded from the application’s resources, you don’t have to be too concerned with image loading time.However, when I load those thumbnails from the web, as I do now with the Magic Panda, scrolling the table can become extremely slow.

Previously, I was loading the thumbnail directly from my table data source’s cellForRowAtIndexPath: method.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"tvCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"tvCell" owner:self options:nil];
        cell = tvCell;
        self.tvCell = nil;
    }
    NSString *url = [picUrls objectAtIndex: indexPath.row];
    UIImageView *img = (UIImageView*)[cell viewWithTag: 2];
    img.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString: url]]];
}

If you don’t have too many rows, a NSMutableDictionary makes a quick & easy image cache. I simply added one method to implement image caching:

NSMutableDictonary *imageCache;

- (UIImage *)getCachedImage: (NSString*)url
{
    UIImage* theImage = [imageCache objectForKey:url];
    if ((nil != theImage) && [theImage isKindOfClass:[UIImage class]]) {
        return theImage;
    }
    else {
        theImage = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString: url]]];
        [imageCache setObject:theImage forKey:url];
        return theImage;
    }
}

When I load my table, I now call getCachedImage rather than fetching the image directly.

    img.image = [self getCachedImage: url];

The result can be seen below:

4 responses to “Quick and easy image caching for UITableViews