加载远程图像的最佳方法是什么?

时间:2012-10-26 06:55:30

标签: ios objective-c uiimage grand-central-dispatch

我一直在研究,并且没有找到这个问题的任何答案 - sendAsynchronousRequest与dataWithContentsOfURL。

哪个效率更高?更优雅?更安全吗?等

- (void)loadImageForURLString:(NSString *)imageUrl
{
    self.image = nil;

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]];
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
     {
         [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
         if (data) {
             self.image = [UIImage imageWithData:data];
         }
     }];
}

OR

- (void)loadRemoteImage
{
    self.image = nil;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSData * imageData = [NSData dataWithContentsOfURL:self.URL];
        if (imageData)
            self.image = [UIImage imageWithData:imageData];

        dispatch_async(dispatch_get_main_queue(), ^{
            if (self.image) {
                [self setupImageView];
            }
        });
    });
}

2 个答案:

答案 0 :(得分:1)

所以我为自己的问题想出了答案:
目前有3种主要方法可以加载图像异步。

  1. NSURLConnection的
  2. GCD
  3. NSOperationQueue
  4. 选择最佳方式对于每个问题都是不同的 例如,在UITableViewController中,我会使用第3个选项(NSOperationQueue)为每个单元格加载图像,并确保在分配图片之前单元格仍然可见。如果单元格不再可见,则应取消该操作,如果VC从堆栈中弹出,则应取消整个队列。

    使用NSURLConnection + GCD时我们无法取消,因此在不需要时应使用此选项(例如,加载恒定的背景图像)。

    另一个好建议是将该图像存储在缓存中,即使它不再显示,也可以在启动另一个加载过程之前在缓存中查找。

答案 1 :(得分:0)

sendAsynchronousRequest更好,更优雅,无论你怎么称呼它。但是,就个人而言,我更喜欢创建单独的NSURLConnection并倾听其delegatedataDelegate方法。这样,我可以:1。设置我的请求超时。 2.使用NSURLRequest的缓存机制设置要缓存的映像(但它不可靠)。 2.观看下载进度。 3.在实际下载开始之前接收NSURLResponse(对于http代码> 400)。等等...而且,它还取决于您的应用程序的情况,如图像大小和其他一些要求。祝你好运!