2012-10-26 104 views
3

我一直在研究,并没有找到任何答案这个问题 - 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]; 
      } 
     }); 
    }); 
} 

回答

1

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

  1. NSURLConnection的
  2. GCD
  3. NSOperationQueue

选择最好的方法是为每一个问题的不同。
例如,在UITableViewController中,我将使用第三个选项(NSOperationQueue)为每个单元格加载图像,并确保在分配图片之前单元格仍然可见。如果单元格不再可见,则应取消操作,如果VC弹出堆栈,则应取消整个队列。

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

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

0

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

+0

下载进度对我来说是使用代表的最大优势 - 但它似乎响应始终在图像的估计大小上显示0。服务器端有问题吗? 除此之外,我认为代表是最麻烦的方法。 – Yariv

相关问题