使用RestKit下载和保存大文件

时间:2012-05-22 15:09:29

标签: objective-c file download save restkit

我正在使用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];
}

我已经检查了仪器中的应用程序是否存在内存泄漏,并看到Live Bytes的{​​{1}}在*Overall Allocations*到达Low Memory Alerts之前不断上升。但是没有泄漏。

删除负责保存文件的行(100 MB)没有改变任何内容,所以我猜问题是在RestKit中的某个地方。

虽然研究我偶然发现method of ASIHTTPRequest允许直接下载文件并认为这样可以解决问题,但不确定。

RestKit中是否存在我错过的直接下载的可能性?

有更好的方法可以下载我应该知道的RestKit文件吗?

1 个答案:

答案 0 :(得分:4)

我遇到了同样的问题,遗憾的是我认为除了修改本地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,它就会自动为您附加。