Ios – Loading an image into UIImage asynchronously


I'm developing an iOS 4 application with iOS 5.0 SDK and XCode 4.2.

I have to show some post blogs into a UITableView. When I have retreived all web service data, I use this method to create an UITableViewCell:

- (BlogTableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
    static NSString* cellIdentifier = @"BlogCell";

    BlogTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
        NSArray* topLevelObjects =  [[NSBundle mainBundle] loadNibNamed:@"BlogTableViewCell" owner:nil options:nil];

        for(id currentObject in topLevelObjects)
            if ([currentObject isKindOfClass:[BlogTableViewCell class]])
                cell = (BlogTableViewCell *)currentObject;

    BlogEntry* entry = [blogEntries objectAtIndex:indexPath.row];

    cell.title.text = entry.title;
    cell.text.text = entry.text; = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL]]];

    return cell;

But this line: = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL]]];

it is so slow ( has a http url).

Is there any way to load that image asynchronously? I think it is difficult because tableView:cellForRowAtIndexPath is called very often.

Best Solution

I wrote a custom class to do just this, using blocks and GCD:


#import <Foundation/Foundation.h>

@interface WebImageOperations : NSObject {

// This takes in a string and imagedata object and returns imagedata processed on a background thread
+ (void)processImageDataWithURLString:(NSString *)urlString andBlock:(void (^)(NSData *imageData))processImage;


#import "WebImageOperations.h"
#import <QuartzCore/QuartzCore.h>

@implementation WebImageOperations

+ (void)processImageDataWithURLString:(NSString *)urlString andBlock:(void (^)(NSData *imageData))processImage
    NSURL *url = [NSURL URLWithString:urlString];

    dispatch_queue_t callerQueue = dispatch_get_current_queue();
    dispatch_queue_t downloadQueue = dispatch_queue_create("com.myapp.processsmagequeue", NULL);
    dispatch_async(downloadQueue, ^{
        NSData * imageData = [NSData dataWithContentsOfURL:url];

        dispatch_async(callerQueue, ^{


And in your ViewController

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    // Pass along the URL to the image (or change it if you are loading there locally)
    [WebImageOperations andBlock:^(NSData *imageData) {
    if (self.view.window) {
        UIImage *image = [UIImage imageWithData:imageData]; = image;


It is very fast and will load the images without affecting the UI or scrolling speed of the TableView.

*** Note - This example assumes ARC is being used. If not, you will need to manage your own releases on objects)

Related Question