Does NSURLConnection Block the Main/UI Thread

前端 未结 4 1191
心在旅途
心在旅途 2020-12-14 13:32

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:(UITableVi

相关标签:
4条回答
  • 2020-12-14 13:42

    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];
    
    0 讨论(0)
  • 2020-12-14 13:46

    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.

    0 讨论(0)
  • 2020-12-14 13:57

    It sounds like you're doing a synchronous download.

    http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html#//apple_ref/doc/uid/20001836-170129

    Read there, and make sure you're using the async APIs

    0 讨论(0)
  • 2020-12-14 14:04

    If you mean "does NSURLConnection execute on the main thread?", then yes, I believe that's the case. The connection is opened and the delegate methods are executed on the main thread. I haven't found any documentation to suggest otherwise, and you can verify it by debugging.

    I think your supposition that the UITableView scrolling blocks the NSURLConnection callbacks in the main run loop is correct.

    You've already posted one solution, spawning a thread for your selector. Another alternative would be to execute your downloads as NSOperations, which has a couple of benefits:

    • If you force the operations to run concurrently (see Dave Dribin's excellent post on this), you can limit the number of simultaneous downloads, which might be desirable if you have a very large number of images in your table. You say your downloads occur "almost instantly", but that may not be the case if your user is on a slow connection and your table contains a lot of images.
    • You can cancel all the operations if the user does something that makes the image downloads irrelevant, like executing another search.

    Dave Dribin's approach, which I use, forces the connections to execute back on the main thread, but that probably isn't necessary for your purposes--you could use your current approach of calling back to the main thread after your images download.

    0 讨论(0)
提交回复
热议问题