Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does NSURLConnection Block the Main/UI Thread

I am downloading images in table view cells as they scroll onto the screen. For UX reasons, I start downloading the images in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. I do not wait until the table view is done scrolling. When the table view cell is set, I start downloading images that I do not have already. However, they do not seem to fully download until the table view stops moving. As soon as it stops moving, the images almost download instantly.

Is there anyway to use NSURLConnection where it is not blocked by the main UI thread? Or, is there a way where these images will download very quickly while the table view is being scrolled.

** EDIT **

To prove that NSURLConnection is slower I used NSThread to detach a new selector in a different thread. I then download the data and call back to the main thread where I create a UIImage and show it in the table view. This method works MUCH faster.

Personally, I think that NSURLConnection is getting thrown into the event loop where the UITableView scrolling is blocking it.

like image 470
rickharrison Avatar asked Jul 13 '10 03:07

rickharrison


2 Answers

Read NSDefaultRunLoopMode vs NSRunLoopCommonModes for a good explanation of why all the download delegate notifications are queued up, but to download while scrolling when using the main thread change from this:

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

to this:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
                                                              delegate:self
                                                      startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
                      forMode:NSRunLoopCommonModes];
[connection start];
like image 111
Gabe Avatar answered Sep 24 '22 15:09

Gabe


I have experienced this problem before. The asynchronous delegate methods of NSURLConnection are not firing while a scrollView is being scrolled. Although the downloading works in the background, your main thread is not informed of new images. Just like you, I believe the problem is related to scrollviews being scrolled in an inner NSRunLoop with a different RunLoopMode. I have been talking to Apple staff about this and have them look at my code, but we couldn't work out a solution.

On the other hand Jeff LaMarche has this post on his blog, where he does the same thing, and it works as expected. I have not been able to figure out what he does differently (mainly due to not having time), but this may be worth a look.

like image 30
tonklon Avatar answered Sep 24 '22 15:09

tonklon