Loading an image into UIImage asynchronously
I wrote a custom class to do just this, using blocks and GCD:
WebImageOperations.h
#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;@end
WebImageOperations.m
#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, ^{ processImage(imageData); }); }); dispatch_release(downloadQueue);}@end
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 processImageDataWithURLString:entry.photo andBlock:^(NSData *imageData) { if (self.view.window) { UIImage *image = [UIImage imageWithData:imageData]; cell.photo.image = 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)
In iOS 6 and later dispatch_get_current_queue gives deprecation warnings.
Here is an alternative that is a synthesis of the @ElJay answer above and the article by @khanlou here.
Create a category on UIImage:
UIImage+Helpers.h
@interface UIImage (Helpers)+ (void) loadFromURL: (NSURL*) url callback:(void (^)(UIImage *image))callback;@end
UIImage+Helpers.m
#import "UIImage+Helpers.h"@implementation UIImage (Helpers)+ (void) loadFromURL: (NSURL*) url callback:(void (^)(UIImage *image))callback { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ NSData * imageData = [NSData dataWithContentsOfURL:url]; dispatch_async(dispatch_get_main_queue(), ^{ UIImage *image = [UIImage imageWithData:imageData]; callback(image); }); });}@end
Take a look at SDWebImage:
https://github.com/rs/SDWebImage
It's a fantastic set of classes that handle everything for you.
Tim