ASIHTTPRequest - 来自缓存的数据始终为空
Posted
技术标签:
【中文标题】ASIHTTPRequest - 来自缓存的数据始终为空【英文标题】:ASIHTTPRequest - data from cache always empty 【发布时间】:2011-06-25 13:50:26 【问题描述】:我正在我的 iPhone/iPad 应用程序中下载图像 - 因为它们大部分时间都保持不变,所以我想将它们缓存在磁盘上:
ASIDownloadCache *cache = [ASIDownloadCache sharedCache];
[asiRequest setDownloadCache:cache];
[asiRequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[asiRequest setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
[asiRequest setSecondsToCache:60*60*24*30]; // Cache for 30 days
[asiRequest setDelegate:self]; // A delegate must be specified
[asiRequest setDidFinishSelector:@selector(requestFinished:)];
[asiRequest startAsynchronous];
在我的requestFinished-method中,可以识别出缓存是成功的,但是我的request-object里面的数据是空的;我错过了什么?
- (void) requestFinished:(ASIHTTPRequest *)request
if ([request didUseCachedResponse])
NSLog(@"cache, size: %i", [[request responseData] length]); // is always zero
[self buildImageWithData:[request responseData]];
[...];
非常感谢!
编辑 1: 我的完整代码不起作用:第一次,我得到“未缓存”语句,从那时起,“缓存,大小:0”......我有不知道为什么:(
- (void)viewDidLoad
[super viewDidLoad];
for (int i = 0; i < 10; i++)
asiRequest = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.myimageserver.com/myimage.jpg"]];
ASIDownloadCache *cache = [ASIDownloadCache sharedCache];
[asiRequest setDownloadCache:cache];
[asiRequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[asiRequest setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
[asiRequest setSecondsToCache:60*60*24*30]; // Cache for 30 days
[asiRequest setDelegate:self]; // A delegate must be specified
[asiRequest setDidFinishSelector:@selector(requestFinished:)];
[asiRequest startAsynchronous];
- (void) request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
self.imageDataLoadedFromURL = [NSMutableData data];
- (void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
[imageDataLoadedFromURL appendData:data];
- (void) requestFinished:(ASIHTTPRequest *)request
if ([request didUseCachedResponse])
NSLog(@"cache, size: %i", [[request responseData] length]); // is always zero
else
NSLog(@"not cached");
编辑 2: 似乎缓存已经包含 0 字节图像;所以这不是从缓存中读取而是写入它的问题......
编辑3:你可以从http://tinyurl.com/68wuwj2下载小测试项目
【问题讨论】:
【参考方案1】:您能否设置断点,清除缓存(例如,删除您的应用程序),然后单步执行这段代码(ASIDownloadCache.m,第 184 行,方法 storeResponseForRequest):
if ([request responseData])
[[request responseData] writeToFile:dataPath atomically:NO];
else if ([request downloadDestinationPath] && ![[request downloadDestinationPath] isEqualToString:dataPath])
NSError *error = nil;
[[[[NSFileManager alloc] init] autorelease] copyItemAtPath:[request downloadDestinationPath] toPath:dataPath error:&error];
检查走哪条路径,检查request.responseData的大小。
** 编辑 **
你的问题是你对 didReceiveData 的使用:
- (void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
[imageDataLoadedFromURL appendData:data];
引用 asi http 请求文档:
如果您需要将响应处理为 它进来了(例如,你想 使用流解析器来解析 仍在进行中的响应 下载),让你的代表 实现请求:didReceiveData:(见 ASIHTTPRequestDelegate.h)。 请注意 当你这样做时,ASIHTTPRequest 将 不填充 responseData 或写入 响应 downloadDestinationPath - 您必须自己存储响应 如果需要。
最后一句话似乎也适用于缓存数据。
这可能是 asihttprequest 中的一个错误,实际上在这种情况下它不应该将数据写入缓存,或者应该确保它正在写入有效数据 - 目前看起来它写入了一个无效的缓存条目。您是否需要在数据到达时对其进行处理?如果不只是删除 'didReceiveBytes' 并仅使用 requestFinished 中 request.responseData 中提供的数据。
【讨论】:
@"接收数据的大小:%d 个字节", [[request responseData] length] => 给出 0 个字节;它采用第一个路径,因此它将 0 写入文件... 如果您完全禁用缓存(即停止读取或写入缓存,因此它将始终从服务器获取),您的应用程序是否工作?看来您的问题可能不是缓存问题,而是服务器返回的数据有问题。 感谢您的测试应用程序,这让它变得更加容易 - 我已经更新了我的答案!【参考方案2】:您的代码对我来说似乎是正确的。
我唯一能想到的是,您的缓存中可能有一些“损坏”的数据,例如存储零长度数据的情况。您可以尝试只删除一次缓存或只使用一次ASIDoNotReadFromCacheCachePolicy
策略(以便“清除”缓存)。
如果这没有帮助,我会在您的requestFinished:
中设置一个断点,然后从那里准确检查据称从缓存中检索数据时 ASIHTTP 中发生了什么。这比听起来容易。
【讨论】:
这就是我的观点;在 requestFinished:-method 中,数据已经是空的。不幸的是,ASIDoNotReadFromCacheCachePolicy 不起作用……我真的不知道这里出了什么问题……【参考方案3】:注释掉这个方法:
(void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
[imageDataLoadedFromURL appendData:data];
【讨论】:
【参考方案4】:试试这个,告诉我你得到了什么:
- (void) requestFinished:(ASIHTTPRequest *)request
NSLog(@"Size of received data: %d bytes",[[request responseData] length]); //THIS LINE
if ([request didUseCachedResponse])
NSLog(@"cached");
else
NSLog(@"not cached");
然后尝试将此方法更改为:
- (void) request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
[self.imageDataLoadedFromURL setLength:0];
并确保您使用 self.imageDataLoadedFromURL
作为 NSMutableData
【讨论】:
%lu 是不可能的(编译器错误);我只能使用“%u”,结果也是 0。 didReceiveResponseHeaders 的更改没有任何后果; imageDataLoadedFromURL 是 NSMutableData... 没有改变任何东西;另请参阅我更新的原始帖子;似乎写入缓存不起作用... 哦Size of received data: %d bytes
总是显示 0 ?您还没有使用更新的代码或您的真实图像是 0 字节
我的真实图像是 0,因为我在缓存中找到了它(请参阅我的原始帖子的编辑)
我的意思是你的服务器图像。Size of received data: %d bytes
总是显示 0 吗?【参考方案5】:
我尝试运行您的应用。亚历山大的建议是对的。
注释掉这个方法:
(void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
在注释掉这个方法时,调用的 requestDone 方法将具有整个请求内容,因此具有大小。
【讨论】:
以上是关于ASIHTTPRequest - 来自缓存的数据始终为空的主要内容,如果未能解决你的问题,请参考以下文章
ASIHTTPRequest 下载缓存问题 - 无法在缓存中保存/加载日期
目标 C - 使用 ASIHTTPRequest 来自 GET 的 HTTP/0.9 响应