Sdwebimage: sd_setImageWithPreviousCachedImageWithURL method polls disk cache synchronously

Created on 5 Jul 2014  路  10Comments  路  Source: SDWebImage/SDWebImage

Stumbled onto this while working on my pull request and it seems like an error.

- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *), which is assumed to be called on the main thread, calls [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key]; synchronously.

Shouldn't it be using something like - (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(void (^)(UIImage *image, SDImageCacheType cacheType))doneBlock?

As a side note, this method is also missing from UIButton. Was that intentional?

Thanks!

awaiting response feature

Most helpful comment

Any progress?

All 10 comments

@DimaVartanian this method for using the previously cached image was just added (see #541 and #599) to avoid the flickering between placeholder and the image that is cached (in that case). The author just added it for UIImageView. You are correct, we should rewrite this in an async manner. Are you available for this?

Yeah I'll try to tackle this within the next day or two. We can also add it to UIButton, I guess?

Yeap, to be consistent is should be available for UIButton and MKAnnotationView

@DimaVartanian any updates? Did you managed to do anything?

Has any progress been made on this?

Looks like it didn't.

Any progress?

To answer this question, you should considerate the runLoop as well. UIKit(Core Animation) will do rendering composition during the same runloop, so if you call these:

imageView.image = image1;
sleep(1);
imageView.image = image2;

is different from

imageView.image = image1;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    sleep(1);
    dispatch_async(dispatch_get_main_queue(), ^{
        imageView.image = image2;
    });
});

The second one will trigger a flash because image1 will be rendered and then image2 will be rendered after 1 second.

But the first one will just show image2 after 1 second, the image1 is ignored by UIKit &Core Animation (this may has impact on frame rate because of blocking the main queue).

So, next, what cases do you need ? If you want to keep the current image for non-reused imageView, use SDWebImageDelayPlaceholder instead.

If you want to use it for reused imageView (tableViewCell/collectionViewCell), current implementation will force to query the memory-disk cache. So this is adoptable for normal use case.(You'll never disable memory cache when you decide to use this method, right ?). For advanced control on reused-imageView caching, you need to implement it yourself.

If you think that disk cache is important(means if the disk cache contains the image, load it, don't care about blocking main queue!), use SDWebImageQueryDiskSync options with the normal public API(sd_setImageWithURL:) can solve this issue. If you find that disk read time is large, you can also try using NSDataReadingMappedIfSafe in diskCacheReadingOptions, this will use mmap instead of fread for NSData

If you think that you need keep a high frame rate and do not want disk cache produce a flashing (Because disk cache is really fast compared to network, but really slow compared to memory), you can just disable disk cache use SDWebImageCacheMemoryOnly. Or you can create a animation after the image is set to reduce this visual effect.

2175 Merged. Consider using SDWebImageQueryDiskSync instead.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bembem1011 picture bembem1011  路  6Comments

cyanzhong picture cyanzhong  路  5Comments

paul-lavoine picture paul-lavoine  路  4Comments

ToLengSon picture ToLengSon  路  3Comments

Ricardo1980 picture Ricardo1980  路  6Comments