2010-07-13 59 views
6

我正在将表格视图单元格中的图像下载到屏幕上。出于UX的原因,我开始下载- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath中的图像。我不等到表视图完成滚动。当表格视图单元格被设置时,我开始下载我没有的图像。但是,它们似乎没有完全下载,直到表视图停止移动。只要它停止移动,图像几乎立即下载。NSURLConnection是否阻止主/ UI线程

无论如何要使用NSURLConnection它没有被主UI线程阻塞?或者,有没有办法在桌面视图滚动时快速下载这些图像。

**编辑**

为了证明NSURLConnection的慢我用NSThread在不同的线程脱离了新的选择。然后我下载数据并回调到创建UIImage的主线程,并在表格视图中显示它。这种方法工作速度更快。

就我个人而言,我认为NSURLConnection会被引入UITableView滚动阻塞的事件循环中。

+0

用户能够以比电话能够击中网络并下载图像更快的速度滚动表格。对我来说听起来很正常... – psychotik 2010-07-13 03:50:57

+0

我刚刚通过分离新的NSThread实现了同样的解决方案,并且它的下载速度更快。 – rickharrison 2010-07-13 04:46:28

+1

绝对下载使用事件循环。这听起来似乎合理,滚动是以某种方式关闭它。 – JeremyP 2010-07-13 07:58:44

回答

2

我以前也遇到过这个问题。当scrollView被滚动时,NSURLConnection的异步委托方法不会触发。虽然下载在后台工作,但您的主线程不会被通知新图像。就像你一样,我相信这个问题与scrollview在一个内部NSRunLoop中使用不同的RunLoopMode滚动有关。我一直在与苹果员工讨论这个问题,让他们看看我的代码,但我们无法找到解决方案。

另一方面Jeff LaMarche在他的博客上有this post,他在那里做同样的事情,并且它按预期工作。我一直无法弄清楚他做了什么不同(主要是因为没有时间),但这可能值得一看。

1

如果你的意思是“NSURLConnection在主线程上执行吗?”,那么是的,我相信是这样的。连接打开并且委托方法在主线程上执行。我还没有找到任何文档来建议,您可以通过调试来验证它。

我认为你的假设UITableView滚动阻塞主运行循环中的NSURLConnection回调是正确的。

您已经发布了一个解决方案,为您的选择器产生一个线程。另一种方法是执行您下载的NSOperations,它有几个好处:

  • 如果强行操作,同时运行(见Dave Dribin's excellent post on this),你可以限制同时下载的数量,这可能是可取的如果你的桌子上有大量的图片。您说您的下载“几乎是即时”发生,但如果您的用户连接速度较慢并且您的桌面包含大量图像,则可能不是这种情况。
  • 如果用户执行的操作使图像下载无关紧要(如执行其他搜索),则可以取消所有操作。

我使用的Dave Dribin的方法强制连接在主线程上执行,但这可能对您的目的没有必要 - 您可以使用当前的方法调用回主线程你的图片下载后。

22

NSDefaultRunLoopMode vs NSRunLoopCommonModes对于为什么所有的下载委托通知排队一个很好的解释,但在使用此主线程变化时滚动下载:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request 
                   delegate:self]; 

这样:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request 
                   delegate:self 
                 startImmediately:NO]; 
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] 
         forMode:NSRunLoopCommonModes]; 
[connection start]; 
+0

太棒了,谢谢。 – Sam 2012-12-04 18:00:46