Sunday, January 29, 2012

Grand central dispatch plus blocks = bliss

I've been doing some iOS programming recently and needed to load a UITableView with images from a web site.

You don't want to load images synchronously as the view scrolls or it kills the user interface response so that needs to be done in another thread. There is some nice code around to do that but after watching the Stanford lecture on the topic I'm totally turned on to the GCD block pattern where a lump of code is written in line but gets run in another thread.

Here's a snippet from my - (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath

// Load the image with an async block executed in another thread
dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
dispatch_async(downloadQueue, ^{
 NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
 UIImage *image = [UIImage imageWithData:imageData];
 // this has to be back on the main thread
 dispatch_async(dispatch_get_main_queue(), ^{
  cell.imageView.image = image;
 });
});
dispatch_release(downloadQueue);

The effect is that you scroll the table view and the images load later. The code looks pretty ugly (to my eye) but it's much simpler than any alternative and great to have it right there in line rather than off in another mystery object.

1 comment:

Anonymous said...

just what i needed - thanks man\!