SDWebImage:下载图片并为关键字存储到缓存中

28

您好,我正在项目中使用SDWebImage框架,想要下载并且缓存图片,但我觉得我的代码可能会把同一张图片存储两次?请问有没有什么方法可以通过一个键值只将图片存储一次到缓存中呢?以下是我的代码。

         SDWebImageManager *manager = [SDWebImageManager sharedManager];
         [manager downloadWithURL:[NSURL URLWithString:url] options:0 progress:^(NSUInteger receivedSize, long long expectedSize) {

          } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {

            if(image){
                NSString *localKey = [NSString stringWithFormat:@"Item-%d", i];
                [[SDImageCache sharedImageCache] storeImage:image forKey:localKey];
            }

          }];  

有我漏掉的东西吗?看起来在我的分配工具中执行此操作会导致大量的内存堆积。

11个回答

32

我很惊讶没有人回答这个问题,但我有一个类似的问题,并找到了这个解决方法,所以我会为那些未来查看此内容的人回答(假设你现在已经解决了这个问题)。

直接回答你的问题,是的,你正在对该图片进行两次缓存。

SDWebImageManager 的下载调用会自动使用基于图片 URL 的 absoluteString 作为键进行缓存。如果你想使用自己的键,可以使用 SDWebImageDownloader 上的下载调用,据我所知,默认情况下不会进行缓存。从那里开始,你已经在使用 sharedImageCache 进行缓存并使用任何你想要的键进行缓存。

除此之外,在任何情况下,你看到分配量堆积起来是很奇怪的,因为 SDWebImage 通常喜欢将缓存到磁盘而不是内存中。也许同时发生了其他事情?


你的意思是如果我们为每个(固定下载图像URL)设置键,它就不会在网络上触发下载事件了吗?对吗?并且它会使用以前的缓存吗? - kalpesh jetani
我已经有一段时间没有看过这个了,但是如果你计划使用特定的缓存键存储图像,那么在发出下载请求之前,应该检查[SDImageCache sharedImageCache]中是否存在该图像。如果没有,请使用您自己的特定键存储它,以便下次使用。现在可能已经改变了,但是如果您要以这种方式进行操作,应该使用SDWebImageDownloader,然后使用自己的键进行存储。 - Stakenborg

25

Swift 中使用下面的代码来下载图片并将其存储在缓存中:

Swift 中使用下面的代码来下载图片并将其存储在缓存中:

//SDWebImageManager download image with High Priority 

    SDWebImageManager.sharedManager().downloadImageWithURL(NSURL(string: imageUrl), options: SDWebImageOptions.HighPriority, progress: { (receivedSize :Int, ExpectedSize :Int) in
            SVProgressHUD.show()
            }, completed: { (image :UIImage!, error:NSError!, cacheType :SDImageCacheType, finished :Bool,imageUrl: NSURL!) in
                if(finished) {
                    SVProgressHUD.dismiss()
                    if((image) != nil) {
                        //image downloaded do your stuff
                    }
                }
        })

Swift 3 版本:

SDWebImageManager.shared().downloadImage(with: NSURL(string: "...") as URL!, options: .continueInBackground, progress: { 
(receivedSize :Int, ExpectedSize :Int) in

}, completed: { 
(image : UIImage?, error : Error?, cacheType : SDImageCacheType, finished : Bool, url : URL?) in

})

Objective-C版本:

[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:imageUrl] options:SDWebImageDownloaderUseNSURLCache progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {

                    if (image && finished) {
                        // Cache image to disk or memory
                        [[SDImageCache sharedImageCache] storeImage:image forKey:CUSTOM_KEY toDisk:YES];     
                    }
                }]; 

谢谢Parth。我还没有研究过Swift版本,但是Swift版本是否有SDWebImageDownloader类实现来使用自定义键缓存图像而不是URL? - AgnosticDev
是的,Swift 版本有用于使用自定义键缓存图像的类。您可以使用以下代码:SDImageCache.sharedImageCache().storeImage(image, forKey: "(file.attachmentFileName!)_(file.fileId)")。 - parth
1
太棒了!使用自定义键缓存图像终于成功了。 - yuchen
使用最新版本的 SDWebImage 5.0,这个方法已经不再适用。SDWebImageManager.shared 没有该方法。 - Rikh

16

SWIFT 5 和最新的 SDWebImage 5.2.3

SDWebImageManager.shared.loadImage(
    with: album.artUrlFor(imageShape: .square),
    options: .continueInBackground, // or .highPriority
    progress: nil,
    completed: { [weak self] (image, data, error, cacheType, finished, url) in
        guard let sself = self else { return }

        if let err = error {
            // Do something with the error
            return
        }

        guard let img = image else {
            // No image handle this error
            return
        }

        // Do something with image
    }
)

如何使用@DoesData缓存视频URL中的图像 - Dilip Tiwari

11

Swift4:

SDWebImageManager.shared().loadImage(
        with: URL(string: imageUrl),
        options: .highPriority,
        progress: nil) { (image, data, error, cacheType, isFinished, imageUrl) in
          print(isFinished)
}

5

Swift 4.0.

let url = URL(string: imageUrl!)

SDWebImageManager.shared().imageDownloader?.downloadImage(with: url, options: .continueInBackground, progress: nil, completed: {(image:UIImage?, data:Data?, error:Error?, finished:Bool) in
     if image != nil {. 

     }
})

5
SDWebImage将图像同时缓存到磁盘和内存中。让我们看一下这个过程:
  1. 您从新的URL下载图像。
  2. 它被缓存在内存和磁盘中。
  3. 如果您在同一会话中调用该图像,则会从内存中检索它。
  4. 假设您重新运行应用程序并访问URL,它将检查内存,其中不会有该图像,然后它将检查磁盘并从那里获取它。如果没有,则会下载它。
  5. 默认设置下,图像在磁盘上保存一周。
因此,您不需要担心缓存。SDWebImage非常好地处理了它。
如果您想按照HTTP缓存标头进行设置,还可以自定义实现缓存以及从缓存中刷新图像。
您可以在他们的GitHub页面这里找到完整的详细信息。

4
尝试使用APSmartStorage(https://github.com/Alterplay/APSmartStorage)代替SDWebImage。
APSmartStorage可以智能地从网络获取数据,并自动以智能可配置的方式将数据缓存到磁盘或内存中。对于您的任务应该足够好用。

会调查一下。谢谢。 - AgnosticDev

1

使用SDWebImage可以下载图片并手动存储到本地内存。

使用SDWebImage下载的图片可以手动存储到本地内存

func saveImage(url: URL, toCache: UIImage?, complation: @escaping SDWebImageNoParamsBlock) {
    guard let toCache = toCache else { return }

    let manager = SDWebImageManager.shared()
    if let key = manager.cacheKey(for: url) {
        manager.imageCache?.store(toCache, forKey: key, completion: complation)
    }
}

从内存中使用图片URL加载图像。
static func imageFromMemory(for url: String) -> UIImage? {
    if let encoded = url.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed),
        let url = URL(string: encoded) {
        let manager = SDWebImageManager.shared()
        if let key: String = manager.cacheKey(for: url),
            let image = manager.imageCache?.imageFromMemoryCache(forKey: key) {
            return image
        }
    }
    return nil
}

0

//创建一个自定义的ImageView,并通过数组(indexPath.row)传递图像URL

(void) loadImage:(NSString *)imageLink{

    imageLink = [imageLink stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

    SDWebImageManager *manager = [SDWebImageManager sharedManager];

    [manager loadImageWithURL:[NSURL URLWithString:imageLink] options:SDWebImageDelayPlaceholder progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {

    } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {

        imageFrame.image = image;

    }];
}

0

Swift 5.1

import UIKit
import SDWebImage

extension UIImageView{
    func downloadImage(url:String){
      //remove space if a url contains.
        let stringWithoutWhitespace = url.replacingOccurrences(of: " ", with: "%20", options: .regularExpression)
        self.sd_imageIndicator = SDWebImageActivityIndicator.gray
        self.sd_setImage(with: URL(string: stringWithoutWhitespace), placeholderImage: UIImage())
    }
}

如何使用

let myUrl = "https://www.example.com"
myImageView.downloadImage(url: myUrl)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接