所以我在这里读了几篇关于排队系统的帖子,但我似乎无法弄清楚如何做我想要的。目前我要访问一个页面并使用循环加载图像,每个图像都使用此处看到的异步调度。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//Load Image Code Goes Here
dispatch_async(dispatch_get_main_queue(), ^{
//Display Image Code Goes Here After Loading.
});
});
这很好用,但是我需要能够销毁这个队列或等到它完成之后再做其他事情。基本上某些页面有几十个和几十个图像,所以它们都开始加载,然后我去应用程序中一个完全独立的区域并完成一个完全不同的图像加载(1-2个图像),它将花费将近一分钟,因为它是仍在等待其他图像加载。有没有办法摧毁我的旧队列或暂停?我见过一个人说'#34;你可以,但它会破坏传入的数据"这很好,因为图像只会在新页面加载时重新下载。有任何想法吗?
答案 0 :(得分:1)
稍微不同的方法是仅发送一些图像以启动,然后在任何先前的请求完成时发送另一个图像。这是代码的样子
- (IBAction)startButtonPressed
{
self.nextImageNumber = 1;
for ( int i = 0; i < 2; i++ )
[self performSelectorOnMainThread:@selector(getImage) withObject:nil waitUntilDone:NO];
}
- (void)getImage
{
if ( self.view.window && self.nextImageNumber <= 6 )
{
int n = self.nextImageNumber++;
NSLog( @"Requesting image %d", n );
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://images.apple.com/v/iphone-5s/gallery/a/images/download/photo_%d.jpg", n]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:url]];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog( @"Received image %d", n );
[self updateImage:image forView:n];
[self performSelectorOnMainThread:@selector(getImage) withObject:nil waitUntilDone:NO];
});
});
}
}
正在下载的图片通过“photo_6.jpg”命名为“photo_1.jpg”。通过请求前两张照片开始该过程。当其中一个完成时,将分派下一个请求,依此类推,直到检索到所有6张照片。代码的关键是
if ( self.view.window && self.nextImageNumber <= 6 )
if
的第一部分检查视图控制器是否仍在屏幕上。当用户离开视图控制器时,self.view.window
将设置为nil
。因此,从视图控制器导航会破坏下载链。
if
的第二部分检查是否所有下载都已完成。这很容易,因为文件名包含数字。对于随机文件名,您可以使用URL填充NSArray,然后通过数组索引,直到结束。
我以2次下载启动了链,因为在该URL上只下载了6个图像。根据图像大小和图像数量,您可能希望从调度更多开始。权衡是最大化带宽使用(从更多开始)与最小化取消时间(以较少开始)。
答案 1 :(得分:0)
如果您正在使用NSURLConnection,您应该在块之外保留对它们的引用,然后如果您离开屏幕,请在每个块上调用[downloadConnection cancel]