I began to make heavy use of blocks and queues, and they were great. I use much less code and it is much easier to create and maintain. But I'm curious about performance. In one case, I show a screen with thumbnail images from the Flickr photo set. The code iterates through all the elements and launches a unique download queue to load each photo at a time. It works fine, but I wonder if I should instead create a static queue for uploading photos, and then send these upload blocks in one queue to manage the blocks efficiently.
I gave an example here.
http://www.smallsharptools.com/Downloads/iOS/UIImage+DownloadImage.zip
The contents of the implementation are also given below. I appreciate an understanding of better performance. (Later, I would like to handle image caching by placing the file in the tmp folder so that they are automatically cleaned periodically.)
How do you manage parallel tasks with blocks? Do you create a static queue and send blocks to a shared queue? Or is the execution below implicitly effectively managing all my tasks?
#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:&response error:&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 && data) { image = [UIImage imageWithData:data]; } // image will be nil if the request failed dispatch_async(callerQueue, ^{ returnImage(image, error); }); }); dispatch_release(downloadQueue); } @end
source share