我已经开始大量使用块和队列了,而且它们很棒。我使用的代码少得多,而且构建和维护也更容易。但我想知道表现。在一个案例中,我正在显示一个充满Flickr照片集缩略图的屏幕。代码遍历所有项目并启动唯一的下载队列以同时下载每张照片。它工作正常,但我想知道是否应该创建一个静态队列来下载照片,然后将这些下载块分派到同一队列,以便它可以有效地管理块。
我在这里上传了一个例子。
http://www.smallsharptools.com/Downloads/iOS/UIImage+DownloadImage.zip
实施内容如下。我很欣赏任何有关更好性能的见解。 (稍后我想通过将文件放在tmp文件夹中来处理图像缓存,以便它们定期自动清除。)
如何使用块管理并发任务?您是否创建了静态队列并将块分派给共享队列?或者下面的实现是否已经有效地隐式管理我的所有任务?
#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
答案 0 :(得分:4)
每次创建1个元素的队列似乎效率低下,但如果在分析期间这会显示为热点,我会感到惊讶。
如果您在Apple的iOS论坛上搜索,您应该能够找到Quinn关于使用NSURLConnection“raw”而不是通过线程的讨论。
答案 1 :(得分:1)
您正在对队列进行同步网络活动。这似乎是一个相当糟糕的想法,因为你阻止线程并强制GCD启动新线程来服务其他块。如果您同时下载了20个图像,那么您的应用程序中将有20个被阻止的线程,而另一个用于实际工作。相反,您应该在单个工作线程上执行异步网络活动。甚至有一段Apple样本代码可以做到这一点,虽然我不能为我的生活记住它的名字。