【问题标题】:How to implement a download queue and active connections management?如何实现下载队列和活动连接管理?
【发布时间】:2013-09-24 20:57:30
【问题描述】:

我有一个应用程序,每个屏幕都需要从 REST API 加载一些图像(甚至可能是 50 个)和一些 JSON。问题是用户可以在所有图像加载之前更改屏幕,并且在新屏幕出现时继续下载,这很糟糕。

我的最终目标是能够在屏幕更改时取消所有活动下载。即使图像尚未完成下载。

排队同时下载不超过 5 张图片也不错。 这是我现在下载图像的方式:

// global queue
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.data objectForKey:@"image_url"]]];
self.image = [UIImage imageWithData:imageData];

dispatch_async(dispatch_get_main_queue(), ^{
    [[DataManager sharedManager] storeImageData:self.image forImageWithID:self.imageID];
    [self.delegate downloadedImage:self];
});

【问题讨论】:

  • 切换到使用NSOperation 进行数据下载,一种选择是开始使用AFnetworking。你永远不应该使用 initWithURL 选项,因为它不能让你对正在发生的事情有足够的控制。

标签: ios objective-c


【解决方案1】:

您应该使用操作队列而不是 GCD。这样,您可以一次将其限制为五个并发请求,并且它们是可取消的。您还应该使用NSURLConnection 而不是dataWithContentsOfURL,这样您就可以在下载过程中取消它。

不过,将 NSURLConnection 放入 NSOperation 可能会很棘手(因为您必须将其安排在运行循环中)。可能最简单的方法是利用第三方类,例如AFNetworking

如果您将操作添加到自己的队列中,只需将其maxConcurrentOperationCount 设置为5,如果您想取消操作,只需调用cancelAllOperations


根据您使用图像的方式,您可能会考虑根本不将图像加载到数组中。例如,如果您只是在UIImageView 对象中填充图像,请考虑使用UIImageView 类别,例如AFNetworking 的UIImageView+AFNetworking 类别:

UIImageView *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"]];

或者您可以使用SDWebImage,它提供了一个稍微丰富的UIImageView 类别。它提供了自己的 UIImageView 方法,称为 setImageWithURL

但是如果您使用UIImageView 类别,您可以使用“延迟加载”,仅在创建图像视图时加载图像。这是UITableViewUICollectionView 等用户界面的理想选择。

【讨论】:

  • 我看了AFNetworking,看来我会尝试一下。但是如何取消与该框架的所有活动连接?这是我的问题。我在自述文件中没有看到此类信息。
  • 如果您将操作添加到您自己的队列中,那么您可以执行标准的NSOperationQueue 方法cancelAllOperations。相应地更新了答案。
  • 我可以使用 AFNetworking 框架来做到这一点,还是必须实现自己的 NSOperationQueue、子类 NSOperation 等?
  • @NikolayDyankov AFNetworking 创建从NSOperation 子类化的对象。因此,您可以将它们添加到您创建和配置的NSOperationQueue。你也可以使用框架的AFHTTPClient,它会为你创建一个操作队列。
  • 到目前为止一切顺利,但我需要能够取消正在下载的图像。必须等待队列中的所有 5 个图像下载,这有点扼杀了这个队列的意义。 3G 连接的等待时间可能会很长。
猜你喜欢
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
相关资源
最近更新 更多