0

SDWebImage is an extension to UIImageView. There is a method:

sd_setImageWithURL(NSURL(string: url), placeholderImage: placeholder, options: options, completed: { image, error, cache, url in 

    //do sth after it is completed
})

But in completed block I cannot decide whether to allow SDWebImage assign the image or not. It is assigned automaticaly without asking developer about permission to do this. The problem arise when I assign the image to UIImageView within UITableViewCell while scrolling the table.

It is obvious that before it finishes downloading, that cell may be reused for different row, and finally there may be a different image.

How to fix it using this library?

In following question: Async image loading from url inside a UITableView cell - image changes to wrong image while scrolling, there is an answer that SDWebImage solve this problem, but it is not true, or I missed sth.

Community
  • 1
  • 1
Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358

2 Answers2

2

This shouldn't be necessary. If you look inside the implementation of the UIImageView category you will see this:

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
    [self sd_cancelCurrentImageLoad];
    objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

What this shows you is that the minute you call setImage it cancels the download associated with the image view instance. Since UITableView reuses its views this should not be an issue. See how they associate the imageView and URL together.

Your issue is probably the fact that you are not resetting your imageView's image property to nil everytime. So inside cellForRow you probably want:

cell.imageView.image = nil
cell.imageView.sd_setImageWithURL(...)
Daniel Galasko
  • 23,617
  • 8
  • 77
  • 97
1

When you start a new load the image view cancels any current load. So, if the image view is reused this problem is avoided.

If you don't have a new image to set for some reason then you can call sd_cancelCurrentImageLoad and explicitly set your placeholder image.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • 1
    the current load might be cancelled but I think the OP isn't actually clearing the UIImageView's image - http://stackoverflow.com/a/34173483/1652402 – Daniel Galasko Dec 09 '15 at 07:58
  • Really? Suppose you start loading `imageA` to cell. Then while downloading that cell is reused, and started loading `imageB`. It finishes, `imageB` is assigned, and then finishes `imageA`. What image will be in reused cell? How does it work? – Bartłomiej Semańczyk Dec 09 '15 at 07:59
  • The download for the first image is cancelled when you ask to download the second so you shouldn't see it. Are you setting a placeholder? – Wain Dec 09 '15 at 08:00
  • No placeholder... I am just asking about how this work. – Bartłomiej Semańczyk Dec 09 '15 at 08:01
  • 1
    If you don't set a placeholder then any old image will remain there until a new one is set. You need to remove that image. You really should use a placeholder... – Wain Dec 09 '15 at 08:04