What is the best practice for running multiple tasks in iOS blocks and queues?

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 
+4
source share
2 answers

It seems inefficient to create a queue of 1 element each time, although I would be surprised if this manifests itself as a hot spot during profiling.

If you search the Apple iOS forums, you can find a Quinn discussion using NSURLConnection "raw" rather than streaming.

+4
source

You are doing synchronous network activity in queues. This seems like a pretty bad idea, as you block threads and force GCD to create new threads to serve other blocks. If you simultaneously upload 20 images, you will have 20 blocked threads in your application, and one more part is actually. Instead, you should perform asynchronous network activity on the same worker thread. There's even an Apple code snippet that does this, although I can't let my life remember what it called.

+1
source

Source: https://habr.com/ru/post/1380224/


All Articles