使用 RestKit 下载和保存大文件
Posted
技术标签:
【中文标题】使用 RestKit 下载和保存大文件【英文标题】:Downloading and saving large files with RestKit 【发布时间】:2012-05-22 15:09:29 【问题描述】:我正在使用 RestKit 在我的应用程序中下载多个文件。只要文件不是太大,一切都像魅力一样。不幸的是,我尝试下载一个大视频文件(大约 230 MB)并得到一个memory warning
并且应用程序崩溃了。
我用下面这行开始下载
[[RKClient sharedClient] get:[NSString stringWithFormat:@"/%@", listItem.filename] delegate:self];
在委托方法中,我将其本地保存在appDirectory/Library/Caches/
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response
NSURL * url = [NSURL fileURLWithPath:[cacheDirectory stringByAppendingPathComponent:response.URL.lastPathComponent]];
[[response body] writeToURL:url atomically:YES];
我检查了 Instruments 中的应用程序是否存在内存泄漏,发现 Live Bytes
for *Overall Allocations*
在 Low Memory Alerts
出现在 100 MB
附近之前一直在上升。不过没有泄漏。
删除负责保存文件的行 ([[response body] writeToURL:url atomically:YES];
) 并没有改变任何东西,所以我猜问题出在 RestKit 的某个地方。
在研究时,我偶然发现了一个method of ASIHTTPRequest
,它允许直接下载文件,并认为类似的方法可以解决问题,但不确定。
RestKit 中是否有我错过的直接下载的可能性?
或
有没有我应该知道的更好的使用 RestKit 下载文件的方法?
【问题讨论】:
【参考方案1】:我遇到了同样的问题,不幸的是我认为除了修改本地 RestKit 副本之外没有其他方法。问题出在- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
,正好在[_body appendData:data];
。如您所见,RestKit 将响应的主体保存在内存中,并在从服务器发送字节时附加字节。这就是您收到内存不足警告的原因。我的解决方案是向 RKRequest 添加一个属性并将数据直接写入文件系统,具体取决于请求是否为大文件请求:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
if ([_request dontKeepBytesInMemory])
if ([[_request delegate] respondsToSelector:@selector(request:didReceivedData:totalBytesExectedToReceive:)])
[[_request delegate] request:_request didReceivedData:data totalBytesExectedToReceive:_httpURLResponse.expectedContentLength];
else
[_body appendData:data];
if ([[_request delegate] respondsToSelector:@selector(request:didReceivedData:totalBytesReceived:totalBytesExectedToReceive:)])
[[_request delegate] request:_request didReceivedData:[data length] totalBytesReceived:[_body length] totalBytesExectedToReceive:_httpURLResponse.expectedContentLength];
我还需要在协议中添加额外的 RKRequest 委托方法,这样我就可以单独处理大响应。原始委托方法定义了totalBytesReceived
,它就是[_body length]
,但是如果您直接将字节写入文件系统,您只需检查当前文件大小即可跟踪下载状态。如果您正在寻找一种将字节直接保存到文件系统的好方法,请查看 NSFileHandle 类 - 它支持文件偏移量,因此您可以将任何 NSData 扔给它,它会自动为您附加它。
【讨论】:
您好,谢谢您的回答。我还没有时间研究这个,但这似乎是合法的。如果有问题,希望很快会回来并提供反馈...... 你能分享你的代码吗?我对使用 restkit 下载大文件很感兴趣... 很遗憾,我现在无法访问代码(更换了雇主),但如果你告诉我你到底卡在哪里,我很乐意指导你。以上是关于使用 RestKit 下载和保存大文件的主要内容,如果未能解决你的问题,请参考以下文章
aiohttp 异步http请求-5.下载大文件边下载边保存(节省内存)