【问题标题】:downloading image is slow even after using Async call in iphone即使在 iphone 中使用异步调用后,下载图像也很慢
【发布时间】:2012-12-31 11:59:47
【问题描述】:

我必须下载 20-25 个 50 Kb- 2 Mb 的图像,并在表格视图中显示它们。 我对此使用了 ASIHTTPRequest 异步请求。我观察到一段时间后应用程序卡住了。这不应该发生,因为我正在使用异步调用。我认为 ASIHTTPRequest 有问题,我观察到 didFinished 选择器在主线程中被调用。我唯一能做的就是

-(void)didFinishedDownloadingImage:(ASIHTTPRequest*)request { NSData *responseData = [请求响应数据]; UIImage *image = [UIImage imageWithData:responseData]; [[data objectAtIndex:request.tag] setImage:image]; [self.tableView reloadData]; }

我认为这不会造成任何问题。同样在 cellforrowatindexpath 我只是这样做

- (UItableViewCell *)tableviewView:(UItableView *)tableview cellForItemAtIndexPath:(NSIndexPath *)indexPath { UserProfile * 用户 = [数据 objectAtIndex:indexpath.row]; UITableViewCell *cell = [tableView dequeueReusableCellWithReuseIdentifier:@"ProfileCell" forIndexPath:indexPath]; 如果(细胞 == 零){ 单元格 = [[UITableViewCell alloc] initWithStyle:UITableViewDefaultStyle]; } NSString *fullname = [NSString stringWithFormat:@"%@\n%@", 用户名,用户名,用户名]; if(user.image != nil) [cell.imageView setImage:user.image]; 别的{ [cell.imageView setImage:[UIImage imageNamed:@"placeholder.jpg"]]; } [cell.label setText:fullname]; 返回单元格; }

但是应用程序很慢并且会冻结 1-2 秒,这是相当长的时间。 我见过可以非常顺利地执行此操作的应用程序。我尝试使用固定大小的 5Kb 图像,使用上述代码可以显着提高性能。我不知道为什么在这种情况下这会对大图像产生影响,因为所有下载都是通过 ASIHTTP 在其他线程中发生的。

【问题讨论】:

  • [self.tableView reloadData] 是一个非常昂贵的操作。选择性地重新加载您需要的单元格。
  • @Srikanth 如何将图像转换为缩略图??
  • @JackLawrence ,我怀疑 setImage 需要时间。因为即使向上或向下滚动,我也会看到滞后。 (滚动表格视图时调用重新加载单元格)如果我一次加载一个或整个表格没有任何区别。

标签: iphone ios objective-c asihttprequest


【解决方案1】:

请将您的框架替换为AFNetworking

你可以简单的使用..

IImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)];
[imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]];

或者...直接在 TableViewCell 中

NSURL *url = [[NSURL alloc] initWithString:[movie objectForKey:@"artworkUrl100"]];
[cell.imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:@"placeholder"]];

“在第二行中,我们通过传递一个 NSURL 告诉图像视图缩略图所在的位置,并传入一个占位符图像,只要我们的请求没有返回响应,就会显示”

就是这样!

这里有一个关于http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_afnetworking/的教程

【讨论】:

  • 这与框架无关。我想一次下载 20 张图像,并在下载完成后显示所有图像(分页之类的东西)。我不能使用 setImageWithURL 来做到这一点,因为它对所有图像都是异步的。此外,仅供参考,我已将其替换为 AFNetworking 操作请求,它给了我相同的结果。最终他们都使用了 NSOperation 队列,这对我使用哪个库没有影响。由于主线程中的图像大小(setImage)很大,因此发生了延迟。渲染大图需要时间。
【解决方案2】:

很容易对延迟/缓慢的应用程序的根本原因做出假设。与其猜测,不如测试你的怀疑?使用 Time Profiler 工具分析您的应用程序。它会告诉你你的应用程序在哪些方法和函数上花费的时间最多。

在您有机会介绍之前,这里有一些想法:

您可以考虑下载全分辨率图像并在后台创建缩略图,然后将它们缓存在 NSCache 对象中。您也可以在后台线程中运行[UIImage imageWithData:responseData];。在与视图层次结构交互之前,它是线程安全的。

选择性地重新加载单个单元格应该比重新加载整个 tableview 更快,尤其是具有大量图像的 tableview。此外,如果您在后台队列上进行所有的网络连接和处理,那么滚动表格视图没有理由变慢。您能向我们展示您对-cellForRowAtIndexPath: 方法的整个实现吗?您提到您认为setImage: 是您的慢点,因为渲染速度很慢。如果重新加载单个单元格,则只需要渲染一个单元格。如果您重新加载整个表格视图,每个单元格都必须重新渲染。

【讨论】:

  • 好点。对我来说完全有意义。我会按照你的建议去做。我不知道如何使用 Time Profile 仪器,但我可以找到它。我还编辑了这篇文章,让你知道完整的 cellForRowAtIndexPath 。如果您能指出一些非常明显的错误,请告诉我。谢谢。
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2021-06-22
  • 2014-08-20
  • 2013-04-20
  • 1970-01-01
  • 2017-02-02
  • 2021-10-22
相关资源
最近更新 更多