使用 NSURLSession 缓慢下载照片

Slow downloading of photos with NSURLSession

我正在使用 NSURLSession API 向我的 Java servlet 请求一些上传到我的服务器上的照片。然后我在一些 UIImageView 中显示设备上的照片。问题是最终显示一张照片可能需要十秒钟,大约 100 ko。不用说这是不可接受的。这是我使用的代码:

@interface ViewPhotoViewController () <UIAlertViewDelegate>

@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic) NSURLSession *session;

@end

- (void)viewDidLoad {
[super viewDidLoad];
NSURLSessionConfiguration *config =
[NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:config
                                             delegate:nil
                                        delegateQueue:nil];
NSString *requestedURL=[NSString stringWithFormat:@"http://myurl.com/myservlet?filename=%@", self.filename];
NSURL *url = [NSURL URLWithString:requestedURL];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"GET"];
[request setURL:url];

//Maintenant on la lance

NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
    NSData *downloadedData = [NSData dataWithContentsOfURL:location
                                                   options:kNilOptions
                                                     error:nil];
    NSLog(@"Done");
    NSLog(@"Size: %lu", (unsigned long)downloadedData.length);
    UIImage *image = [UIImage imageWithData:downloadedData];

    if (image) self.imageView.image = image;
}];
[downloadTask resume];
}

奇怪的是我很快就得到了"Done"和"Size"日志,但是很多秒后照片仍然出现。我的代码有什么问题?

那是因为你的完成块不是在主线程上调用的,这意味着你对 self.imageView.image = image; 的调用不是在主线程上进行的。你真的很幸运它能工作,所有与 UIKit 相关的工作都应该在主线程上完成。

所以用这个替换 if (image) self.imageView.image = image; :

if (image) {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageView.image = image;
    });
}