4

No matter what method is used: iOS 5's [NSURLConnection sendAsynchronousRequest], SDWebImage, or ASIHTTPRequest, what if, while the image is being downloaded, the cell aleady got dequeued (when dequeueReusableCellWithIdentifier is called) and therefore, the new label may now be labeled as “Mary”, while Peter’s image is being downloaded, and when the download is completed, Peter's image is populated into Mary’s box.

It will be better if Mary's image is also being downloaded afterwards and will go into Mary's cell and cover up Peter's photo, but what if

1) Mary's photo takes 1 or 2 seconds to download (cell phone wireless network slow or delay), or the network just choke at that point? Then Peter's photo will show next to the name Mary for 1 or 2 seconds or 20 seconds, or even forever if the network request just failed this time.

2) It will be worst if Mary's data has a privacy setting of "don't show my photo" flag or something, then cellForRowAtIndexPath may actually set a dummy image (dummy avatar) into Mary's imageView, and when Peter's image is downloaded, go into Mary's cell and never get replaced.

Can this be elegantly handled or solved?

By the way, if we use SDWebImage or ASIHTTPRequest, will the issue will there or will it be handled by the class already?

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • 1
    This problem is non-trivial, but fortunately there are ready-made solutions for it. Here is a [link](http://www.markj.net/iphone-asynchronous-table-image/) explaining how. – Sergey Kalinichenko Sep 05 '12 at 00:47
  • @dasblinkenlight so it is to use the class `AsyncImageView` or `HJCache`? `AsyncImageView` seems like a small, good solution, but it is not as often heard of as `SDWebImage` or `ASIHTTPRequest`. – nonopolarity Sep 05 '12 at 01:49
  • I never tried `AsyncImageView`, but the code looks straightforward. It looks like the author has applied the same ideas and implemented HJCache. I would start with `AsyncImageView`, and see if it pulls the trick. If it does, I'd look no further; if it does not, I'd explore HJCache or other alternatives. – Sergey Kalinichenko Sep 05 '12 at 02:46

1 Answers1

2

The UITableViewCell method -prepareForReuse is a great opportunity to cancel outstanding network requests, throw away unneeded caches, and that kind of thing.

+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:] doesn't directly afford a way to cancel the request, but if you set some property or ivar before you begin the request, and then check in the completion handler to be sure that its current value matches what you expect, you can get a similar effect.

Sixten Otto
  • 14,816
  • 3
  • 48
  • 60
  • is there some open source classes that support canceling the data fetching? (if the download size is 2MB or 5MB, a way to cancel the data fetching to speed up the newest request) – nonopolarity Sep 25 '12 at 18:30
  • by the way... an instance variable? coz there might be many cells that got scrolled away... or do we need to subclass UITableViewCell and remember a "userid" (as a property), so that the completion block will check against the userid? (remember the "wanted" userid in a local variable before starting the data fetching, and check it against the userid of the UITableViewCell's userid property) – nonopolarity Sep 25 '12 at 19:25
  • NSURLConnection itself supports canceling the request, but only when used in its usual mode (instantiate one and assign a delegate). That's one of a number of reasons to choose that mode over the new convenience method. – Sixten Otto Sep 26 '12 at 01:33
  • You could put the information in a property of the cell, or use some data structure on the object that owns the table to store many values. My point was mostly remembering that information _somehow_ so that you can check it in the completion block. (Because there's no way to end those requests prior to the block being called.) – Sixten Otto Sep 26 '12 at 01:35