1

我有一个应用程序,每个屏幕都需要从 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];
});
4

1 回答 1

0

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

但是,将 aNSURLConnection放入 aNSOperation可能会很棘手(因为您必须将其安排在 runloop 中)。可能最简单的方法是利用第三方课程,例如AFNetworking

如果将操作添加到自己的队列中,只需将其设置maxConcurrentOperationCount5,如果要取消操作,只需调用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类别,你可以使用“延迟加载”,只有在你创建图像视图时才加载图像。这对于诸如UITableView或之类的用户界面是理想的UICollectionView

于 2013-09-24T12:12:59.577 回答