NSURLCache问题 - 从缓存中释放图像?

时间:2014-11-25 17:50:04

标签: ios objective-c caching

我有一个应用程序,我正在下载相当多的图像供以后显示。

即使没有互联网连接,应用程序也需要运行,因此图像会在一个点上加载并使用NSURLCache保留。

这是一个简洁的解决方案,因为我可以使用普通网络库并轻松利用自定义缓存设置。

我意识到这种类型的缓存并不保证文件在它们到期之前一直存在,因为只要系统认为有必要就可以释放缓存。这不是一个大问题,因为图像应该能够重新下载并因此重新保留。

但是,我注意到它决定从缓存中随机发布图像,而在我再次下载时似乎不会持续存在。我不确定我哪里出错了。

首先,我像这样定义缓存容量:

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:50 * 1024 * 1024
                                                     diskCapacity:200 * 1024 * 1024
                                                         diskPath:@"netcache"];
[NSURLCache setSharedURLCache:URLCache];

(内存50MB,磁盘200MB)

下载图像时(使用AFNetworking)我修改了响应标头以将Cache-Control设置为max-age=31536000,这意味着将响应缓存一年。

NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    // Download completed
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // Download failed
}];

[operation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
    NSURLResponse *response = cachedResponse.response;
    NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse*)response;
    NSDictionary *headers = HTTPResponse.allHeaderFields;

    NSMutableDictionary *modifiedHeaders = headers.mutableCopy;
    modifiedHeaders[@"Cache-Control"] = @"max-age=31536000"; // 1 year in seconds
    NSHTTPURLResponse *modifiedHTTPResponse = [[NSHTTPURLResponse alloc]
                                               initWithURL:HTTPResponse.URL
                                               statusCode:HTTPResponse.statusCode
                                               HTTPVersion:@"HTTP/1.1"
                                               headerFields:modifiedHeaders];

    return [[NSCachedURLResponse alloc] initWithResponse:modifiedHTTPResponse data:cachedResponse.data userInfo:cachedResponse.userInfo storagePolicy:NSURLCacheStorageAllowed];
}];

[self.operationQueue addOperation:operation];

...但似乎图像已经发布,再次下载时甚至不会“重新缓存”。 (我相信它们被报告为缓存,即使它们在设备没有任何连接时尝试显示它们也不会加载。)

稍后使用AFNetworking的UIImageView+AFNetworking.h类别显示图像,如下所示:

[self.imageView setImageWithURL:url];

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。首先,您可以使用AFURLSessionManager的方法

- (void)setDataTaskWillCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block;

同时为所有请求设置缓存块。

第二 - 检查' Cache-Control'响应标题中的字段是“公共”字段。例如:

[someAFHTTPSessionManager setDataTaskWillCacheResponseBlock:^NSCachedURLResponse *(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse)
{
     NSHTTPURLResponse *resp = (NSHTTPURLResponse*)proposedResponse.response;
     NSMutableDictionary *newHeaders = [[resp allHeaderFields] mutableCopy];
     if (newHeaders[@"Cache-Control"] == nil) {
         newHeaders[@"Cache-Control"] = @"public";
     }

     NSHTTPURLResponse *response2 = [[NSHTTPURLResponse alloc] initWithURL:resp.URL statusCode:resp.statusCode HTTPVersion:@"1.1" headerFields:newHeaders];
     NSCachedURLResponse *cachedResponse2 = [[NSCachedURLResponse alloc] initWithResponse:response2
                                                                  data:[proposedResponse data]
                                                              userInfo:[proposedResponse userInfo]
                                                         storagePolicy:NSURLCacheStorageAllowed];
     return cachedResponse2;
}];

第三:如果图像的大小超过总缓存空间的5%,则不会缓存。此外,似乎还有一些额外的隐藏规则。