【问题标题】:iOS - Caching remote imageiOS - 缓存远程图像
【发布时间】:2014-12-17 16:33:42
【问题描述】:

我正在尝试缓存来自网络的图像,以防止过多的网络请求以节省电池和数据。基本思路是:

  1. 生成文件位置字符串
  2. 如果文件存在,则从文件中加载它
  3. 如果它不存在(待办事项:或者如果文件超过一天),则从网络下载图像。保存并加载它。

但是我的代码不起作用,我不知道为什么?

// imagesFileName has been correctly generated as as imageURL
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                     NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagesLibraryPath = [documentsDirectory stringByAppendingPathComponent:@"Images"];
NSString *imagePath = [imagesLibraryPath stringByAppendingPathComponent:imageFileName];


// Do We Have the icon in cache?
if (![[NSFileManager defaultManager] fileExistsAtPath:iconPath]) {
    // File Doesn't Exist - Load Image From URL
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imagesURL]];

    // Save Image
    [imageData writeToFile:imagePath atomically:YES];


    NSLog(@"Downloading & Importing Image");
    return [UIImage imageWithData:imageData];
} else {
    // Load the Image From The File But Update If Needed
    NSLog(@"Loading Image From Cache");
    return [UIImage imageWithContentsOfFile:imagePath];
}

【问题讨论】:

  • 在哪种情况下您遇到了麻烦?从读缓存,还是写缓存?
  • 您的if 语句检查iconPath 是否存在,但我认为您的意思是imagePath?然后您的NSData 调用会从imagesURL 创建一个URL,我认为它应该是imagePath。此外,如果您正在缓存数据,则应将其放在 Library/Caches 文件夹 (NSCachesDirectory) 中,以便操作系统可以在空间不足时删除这些数据,因为它可以由您的应用程序重新下载。将它放在 Caches 文件夹中还可以确保它不会被 iTunes 和 iCloud 自动备份。
  • @ev0lution 我已将 iconPath 更改为 imagePath,这只是一个错字。 imageURL 是指 Web 上从中获取图像的 URL,而 imagePath 是指保存(缓存)文件的位置。如何获取应用的缓存目录?
  • @dgee4 使用NSCachesDirectory 而不是NSDocumentDirectory 来查找Caches 目录。

标签: ios objective-c nsurl nsdocumentdirectory


【解决方案1】:

在其他部分,您只是返回图像位置路径。在这里您需要使用该路径传递图像名称。

所以你的else 部分应该是这样的

else {
        // Load the Image From The File But Update If Needed
        NSLog(@"Loading Image From Cache");
        // e.g Some image name
        NSString *imageName = @"Image1.png";
        [imagePath stringByAppendingPathComponent:imageName];
        return [UIImage imageWithContentsOfFile:imagePath];
    }

【讨论】:

    【解决方案2】:

    这里有一些问题,但首先,你没有说你的代码在什么方面不工作。如果您提供更多信息,也许我们可以提供更多帮助。

    我不建议使用NSDatadataWithContentsOfURL:。此方法同步加载数据(当前函数中的代码执行停止,直到完成)。此方法通常应仅用于本地文件(使用 file:// URL 方案),而不用于远程 URL。查看使用NSURLSessionNSURLConnection 异步加载数据,并阅读Apple 的URL Loading System Programming Guide

    URL 加载系统内置了对缓存的支持,因此您应该尽可能使用它并完全放弃此代码。阅读URL 加载系统编程指南中的Understanding Cache Access 以及NSURLCache article on HSHipster

    如果您确实想编写自己的缓存系统(我不推荐),那么至少:

    • 使用 Caches 目录而不是 Documents 目录(参见 ev0lution 的评论)。
    • 避免使用NSFileManagerfileExistsAtPath:(参见the note in the documentation)。而是尝试从磁盘加载图像,看看是否失败(返回 nil)。

    【讨论】:

    • 我可以使用 iOS 缓存吗?这些链接将我转发到 mac OS X 开发者网站?能否举例说明如何创建这样的缓存并检索和下载数据?
    • URL 加载系统在 iOS 和 OS X 上几乎相同。我还是更改了指向 iOS 文档的链接。
    猜你喜欢
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多