【问题标题】:How to update image in cache when image changed on server with SDWebImage使用 SDWebImage 在服务器上更改图像时如何更新缓存中的图像
【发布时间】:2015-04-19 14:44:56
【问题描述】:

我正在使用 SDWebImage 库从服务器下载图像。 https://github.com/rs/SDWebImage

当图像在服务器上使用相同的 url 更新时,SDWebImage 无法更新缓存的图像。

【问题讨论】:

    标签: ios objective-c caching sdwebimage


    【解决方案1】:

    SDWebImage 默认会做一些缓存,所以如果图像发生变化,最好使用新的 URL。因此,例如,如果您可以控制 URL,并且可以在每次图像更改时更改它,那么您可以这样做。

    如果不是这样,请尝试在 options 字段中使用 SDWebImageRefreshCached 以尊重 HTTP 缓存控制标头,如下所示:

    [imageView setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
              placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
                       options:SDWebImageRefreshCached];
    

    查看更多here

    【讨论】:

    • 我已经尝试过这段代码,但它没有更新图像。问题是,当我更新服务器上的图像并返回上一个屏幕时,重新加载表格视图后图像仍然相同。
    • 您必须确保服务器设置了正确的 HTTP 缓存控制标头。我刚刚测试了一个带有 Master->Detail 结构的示例项目和一个带有从 Dropbox 共享的 URL 中的图像的单个单元格,转到详细信息屏幕,在保持相同名称和共享 URL 的同时更改了 Dropbox 上的图像,确保 Dropbox结束同步,按下应用程序并更新图像。看一下示例项目RefreshCachedImageTest
    • 是的,它适用于保管箱图像。我认为问题出在服务器端。你对服务器端有什么想法吗?
    • 上述方法有效,但现在已弃用,当前可用的方法是这个... [photoView setImageWithURL:[NSURL URLWithString:strPhoto] placeholderImage:[UIImage imageNamed:@"imageName"] options:SDWebImageRefreshCached usingActivityIndi​​catorStyle:UIActivityIndi​​catorViewStyleGray] ;
    • 当服务器 url 上的图像发生变化时,这仍然不起作用....但是 url 与库未检测到图像变化之前相同
    【解决方案2】:

    更新:我实际上已经写了一个关于缓存的完整指南,包括缓存验证https://kean.github.io/blog/image-caching

    SDWebImage 在设置 SDWebImageRefreshCached 选项时使用 NSURLCache。 Apple 的 URL 加载系统实现了 HTTP 缓存,包括缓存响应验证。 HTTP 缓存相当复杂,但是有很多关于 HTTP 缓存的初学者指南:

    基本上,服务器需要在每个响应中包含一些 HTTP 缓存控制标头。有许多不同的策略可用于实施重新验证。您可以使用Last-ModifiedETag。这样,每次客户端发送请求时,它都会自动在您的请求中包含来自先前缓存响应的 Last-ModifiedETag 值。如果图像没有更改,服务器将响应状态码 302(未修改),NSURLConnection/NSURLSession 将透明地为您提供来自NSURLCache 的缓存响应。您不必再次下载数据,每次发出请求时您仍然需要与服务器核对。

    您还可以使用 HTTP 缓存控制指定过期日期。如果使用过期机制,NSURLConnection/NSURLSession 不会重新验证缓存的响应,直到它没有过期。

    有关 HTTP 缓存控制的更多信息,请参见上面的链接。 HTTP 缓存是一种通用缓存机制,应尽可能使用。

    我建议使用Nuke 框架进行图像加载(免责声明:由我撰写)。它默认使用NSURLCache,同时仍然有一个内存缓存来保存解压缩的图像。

    【讨论】:

    • 在不同的注释上,当我尝试 Nuke 时,有没有办法从缓存中删除特定图像并重新加载新图像?还有一种清除整个缓存以便从服务器重新加载所有图像的方法?
    【解决方案3】:

    这是swift 3中每次刷新缓存的代码

    imgCardBack.sd_setImage(with: URL(string: objUserData.back_image!), placeholderImage:UIImage(named: "cardBack"), options: .refreshCached)
    

    【讨论】:

    • 您使用的是最新版本的 SDWebImage 吗?
    • 你使用这种方法的目的是什么?因为主要是在我们更新任何图像时使用,并且它的 url 是相同的,但是图像是新的,我们可以使用上面的方法来获取新的更新图像。
    • 是的,目的与我尝试过的相同。但它仍然无法显示旧图像。
    • 图片 URL 是由后端开发人员创建的吗?或者您为此传递任何名称?
    【解决方案4】:

    斯威夫特 4 只需在 SDWebImage 库中使用以下函数:

    SDImageCache.shared().removeImage(forKey: (ImagePath), withCompletion: nil)
    

    此功能将删除内存和磁盘中保存的现金,之后只需上传您的新图像即可完美运行。

    【讨论】:

    • 请注意,ImagePath 是您用于下载没有 url 标头的图像的路径。
    • 如何从 URL 中获取路径?
    • 它工作.. 图像路径基本上是图像的 URL.. 并且该 URL 用作 NSCache 的键..
    【解决方案5】:

    转到文件 SDWebImageManager.m 中的第 176 行并更改此行

    if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache;
    

    到下面的代码。

    if (options & SDWebImageRefreshCached) {
          // force progressive off if image already cached but forced refreshing
          downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
          // remove SDWebImageDownloaderUseNSURLCache flag
          downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;
          //ignore image read from NSURLCache if image is cached but force refreshing
           downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
    }
    

    对我来说,它就像一种魅力。

    【讨论】:

      【解决方案6】:

      如果 URL 未更改,则 SDWebImage 现在可以知道服务器上的图像已更改。

      【讨论】:

      • 感谢您的回复。在服务器上更新图像时 url 是相同的。问题就在那里,当我更新服务器上的图像并返回上一个屏幕时,重新加载表格视图后图像仍然相同。
      • 是的,图像是一样的,因为它已经被缓存并且 url 没有改变。所以 SDWebImage 无法知道图像在服务器端发生了变化。尝试Edgar 解决方案。
      • 是的,这就是问题所在。但是当我重新加载表格视图时,它应该更新图像。
      • 重新加载 TableView 时会显示缓存的图像,因为 SDWebImage 在内部缓存了您的图像。我的意思是每次重新加载表视图时,SDWebImage 都会检查它是否为特定 URL 缓存了图像,如果有,则显示它。因此,只要不更改 URL,图像也不会更改。
      • 如果您无权访问服务器并且在更改图像时无法更改 URL,我现在看到的唯一解决方案是例如在重新加载表视图之前清除 SDWebImage 缓存。
      猜你喜欢
      • 1970-01-01
      • 2012-10-28
      • 2012-10-13
      • 2011-08-28
      • 1970-01-01
      • 2012-04-23
      • 2016-08-01
      • 2014-04-15
      • 1970-01-01
      相关资源
      最近更新 更多