Reusing UITableViewCell with GCD

Viewed 1012

I'm using Grand Central Dispatch to load images of a UITableViewCell asynchronously. This works well except in some border cases in which the cell is reused, and a previous block loads the wrong image.

My current code looks like this:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    NSString *imagePath = [self imagePathForIndexPath:indexPath];         
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

    dispatch_async(queue, ^{
        UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

        dispatch_sync(dispatch_get_main_queue(), ^{
            cell.imageView.image = image;
            [cell setNeedsLayout];
        });
    });

    return cell;
}

As far as I know GCD queues cannot be stopped. How can this border case be prevented then? Or should I be using something else instead of GCD to solve this problem?

5 Answers
Related