title: What's the best practice for running multiple tasks in iOS blocks and queues?
body: <p>I've started to use blocks and queues heavily and they have been great. I use much less code and it is much easier to build and maintain. But I wonder about performance. In one case I am displaying a screen full of thumbnail images from a Flickr photo set. The code iterates over all items and starts a unique download queue to download each photo concurrently. It's working just fine, but I wonder if I should instead create a single static queue for downloading photos and then dispatch these download blocks to the same queue so that it can manage the blocks efficiently.</p>
  
  <p>I've uploaded an example here. </p>
  
  <p><a href="http://www.smallsharptools.com/Downloads/iOS/UIImage+DownloadImage.zip" rel="nofollow">http://www.smallsharptools.com/Downloads/iOS/UIImage+DownloadImage.zip</a></p>
  
  <p>The implementation contents are also below. I appreciate any insight into better performance. (Later I'd like to handle caching for images by placing the file in the tmp folder so they are automatically cleared out periodically.)</p>
  
  <p>How do you manage concurrent tasks with blocks? Do you create a static queue and dispatch blocks to the shared queue? Or does the implementation below implicitly manage all of my tasks efficiently already?</p>
  
  <pre><code>#import "UIImage+DownloadImage.h"
  
  @implementation UIImage (DownloadImage)
  
  + (void)downloadImageWithURL:(NSURL *)imageURL andBlock:(void (^)(UIImage *image, NSError *error))returnImage {
  
      dispatch_queue_t callerQueue = dispatch_get_current_queue();
      dispatch_queue_t downloadQueue = dispatch_queue_create("Image Download Queue", NULL);
      dispatch_async(downloadQueue, ^{
          UIImage *image = nil;
          NSError *error = nil;
  
          // use the default cache policy to do the memory/disk caching
          NSMutableURLRequest *request = [NSMutableURLRequest 
                                          requestWithURL:imageURL 
                                          cachePolicy:NSURLRequestUseProtocolCachePolicy 
                                          timeoutInterval:15];
  
          NSHTTPURLResponse *response = nil;
          NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&amp;response error:&amp;error];
  
          // 200 indicates HTTP success
          if (response.statusCode != 200) {
              data = nil;
  
              // set the error to indicate the request failed
              NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithFormat:@"Request failed with HTTP status code of %i", response.statusCode], NSLocalizedDescriptionKey, nil];
              error = [NSError errorWithDomain:@"UIImage+DownloadImage" code:response.statusCode userInfo:userInfo];
          }
          else if (!error &amp;&amp; data) {
              image = [UIImage imageWithData:data];
          }
  
          // image will be nil if the request failed
  
          dispatch_async(callerQueue, ^{
              returnImage(image, error);
          });
      });
      dispatch_release(downloadQueue);
  }
  
  @end
  </code></pre>