Bartłomiej Semańczyk
Bartłomiej Semańczyk

Reputation: 61774

How to decide whether to assign image to UIImageView or not, once it finish downloading using SDWebImage?

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.

Upvotes: 0

Views: 280

Answers (2)

Daniel Galasko
Daniel Galasko

Reputation: 24237

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(...)

Upvotes: 2

Wain
Wain

Reputation: 119031

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.

Upvotes: 1

Related Questions