2012-05-22 4 views
0

Я использую RestKit для загрузки нескольких файлов в моем приложении. Пока файлы не слишком большие, все работает как шарм. К сожалению, я попытался загрузить большой видеофайл (около 230 МБ) и получить memory warning, и приложение выйдет из строя.Загрузка и сохранение больших файлов с помощью RestKit

я начать загрузку со следующей строкой

[[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 за *Overall Allocations* продолжал подниматься до Low Memory Alerts. Приблизилось 100 MB. Однако утечек не было.

Удаление строки, ответственной за сохранение файла ([[response body] writeToURL:url atomically:YES];) ничего не изменило, поэтому я думаю, что проблема находится где-то в RestKit.

При исследовании я наткнулся на method of ASIHTTPRequest, который позволяет напрямую скачивать файлы и думать, что что-то подобное может решить проблему, но не уверен.

Есть ли возможность в RestKit для прямой загрузки, которую я пропустил?

или

Есть ли лучший способ для загрузки файлов с RestKit, что я должен знать о?

ответ

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, и он автоматически добавит его для вас.

+0

Эй, спасибо за ответ. У меня еще не было времени изучить это, но это кажется законным. Надеюсь, скоро вернемся к нему и дадим отзывы в случае возникновения проблемы ... – taymless

+0

Можете ли вы поделиться своим кодом? Я очень заинтересован в загрузке больших файлов с помощью restkit ... – fvisticot

+0

К сожалению, у меня нет доступа к коду сейчас (сменил работодателя), но я рад провести вас, если вы скажете мне, где именно вы застряли , – lawicko