[英]Objective-C partially downloaded file and how can i clean memory
I have a problem. 我有个问题。
My function must download extra large files piecemeal. 我的职能部门必须逐步下载特大文件。
The function sends request to server to get part of a static file - for example bytes=50000000-100000000" in 50MB pieces. 该函数向服务器发送请求以获取静态文件的一部分,例如50MB的字节= 50000000-100000000“。
The code concatenates all pieces in one file, so that it does overflow memory downloading. 该代码将所有片段连接到一个文件中,因此不会溢出内存下载。
But i have a problem - memory is not freed in each loop cycle, it just keeps adding up. 但是我有一个问题-内存不是在每个循环周期中释放的,只是不断增加。
NSData *data;
NSOutputStream *stream;
NSString *savePath;
NSMutableURLRequest *request;
NSHTTPURLResponse *response;
int downloadingLimitBlock=50000000;//50MB
int downloadingFileFullSize=0;
int fIndex=0;//tmp
//
//
count=1;//count will changed if size more then minimum size
for (i = 0; i < count; i++)
{
savePath=[NSString stringWithFormat:@"%@%@", videoContentFolderPath,[videoFilesNamesServerList objectAtIndex: fIndex]];//финдекс
stream = [[NSOutputStream alloc] initToFileAtPath:savePath append:YES];
[stream open];
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[videoFilesServerList objectAtIndex: fIndex]]];//финдекс
[request setValue:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9) AppleWebKit/537.71 (KHTML, like Gecko) Version/7.0 Safari/537.71" forHTTPHeaderField:@"User-Agent"];
[request setValue:[NSString stringWithFormat: @"bytes=%d-%d",(((i+1)*downloadingLimitBlock)-downloadingLimitBlock),(((i+1)*downloadingLimitBlock)-1)] forHTTPHeaderField:@"Range"];
data = [NSURLConnection sendSynchronousRequest:request returningResponse: &response error: nil ];
NSLog(@"bytes=%d-%d",(((i+1)*downloadingLimitBlock)-downloadingLimitBlock),(((i+1)*downloadingLimitBlock)-1));
switch (response.statusCode) {
case 206: {
NSString *headerContentRange = [response.allHeaderFields valueForKey:@"Content-Range"];
NSArray *tmpArray=[headerContentRange componentsSeparatedByString:@"/"];
downloadingFileFullSize=[[tmpArray objectAtIndex:1] integerValue];
//recalculate count
count=ceil(downloadingFileFullSize/downloadingLimitBlock)+1;
//recalculate count
NSLog(@"Status code 206 OK");
NSLog(@"sizefromserver %d",downloadingFileFullSize);
break;
}
case 200: {
downloadingFileFullSize = [[response.allHeaderFields valueForKey:@"Content-Length"] integerValue];
NSLog(@"sizefromserver %d",downloadingFileFullSize);
[self logIt:@"Warning! Maybe server is not supporting partly download static content, server returns status code 200, but must 206" ];
///Need add link to server too in logIt
break;
}
default: {
[self logIt:[NSString stringWithFormat:@"Error! while loading video content file,status code is %ld",(long)response.statusCode]];
///Need add link to server too in logIt
break;
}
}
NSUInteger left = [data length];
NSLog(@"part %d lenght %lu",i,(unsigned long)left);
NSUInteger nwr = 0;
do {
nwr = [stream write:[data bytes] maxLength:left];
if (-1 == nwr) break;
left -= nwr;
} while (left > 0);
if (left) {
NSLog(@"stream error: %@", [stream streamError]);
}
[stream close];
data=nil;
stream=nil;
}
//////////////
LOG: 日志:
2013-12-29 00:18:38.890 RAT[151:60b] bytes=0-49999999
2013-12-29 00:18:38.892 RAT[151:60b] Status code 206 OK
2013-12-29 00:18:38.893 RAT[151:60b] sizefromserver 648943692
2013-12-29 00:18:38.894 RAT[151:60b] part 0 lenght 50000000
2013-12-29 00:19:07.624 RAT[151:60b] bytes=50000000-99999999
2013-12-29 00:19:07.626 RAT[151:60b] Status code 206 OK
2013-12-29 00:19:07.627 RAT[151:60b] sizefromserver 648943692
2013-12-29 00:19:07.628 RAT[151:60b] part 1 lenght 50000000
2013-12-29 00:19:52.253 RAT[151:60b] bytes=100000000-149999999
2013-12-29 00:19:52.255 RAT[151:60b] Status code 206 OK
2013-12-29 00:19:52.256 RAT[151:60b] sizefromserver 648943692
2013-12-29 00:19:52.257 RAT[151:60b] part 2 lenght 50000000
2013-12-29 00:20:18.133 RAT[151:60b] bytes=150000000-199999999
2013-12-29 00:20:18.134 RAT[151:60b] Status code 206 OK
2013-12-29 00:20:18.135 RAT[151:60b] sizefromserver 648943692
2013-12-29 00:20:18.136 RAT[151:60b] part 3 lenght 50000000
2013-12-29 00:20:40.666 RAT[151:60b] bytes=200000000-249999999
2013-12-29 00:20:40.667 RAT[151:60b] Status code 206 OK
2013-12-29 00:20:40.668 RAT[151:60b] sizefromserver 648943692
2013-12-29 00:20:40.669 RAT[151:60b] part 4 lenght 50000000
2013-12-29 00:21:04.930 RAT[151:60b] bytes=250000000-299999999
2013-12-29 00:21:04.931 RAT[151:60b] Status code 206 OK
2013-12-29 00:21:04.932 RAT[151:60b] sizefromserver 648943692
2013-12-29 00:21:04.933 RAT[151:60b] part 5 lenght 50000000
2013-12-29 00:21:26.906 RAT[151:60b] bytes=300000000-349999999
2013-12-29 00:21:26.907 RAT[151:60b] Status code 206 OK
2013-12-29 00:21:26.908 RAT[151:60b] sizefromserver 648943692
2013-12-29 00:21:26.909 RAT[151:60b] part 6 length 50000000
And out of memory 而且内存不足
How can I clear memory when each iteration of the loop ends? 循环的每个迭代结束时如何清除内存?
What you want to do is wrap the code inside the loop in an autorelease pool: 您要做的是将代码包装在循环中的自动释放池中:
https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/mmAutoreleasePools.html https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/mmAutoreleasePools.html
When execution exits the auto-release pool, memory that can be freed by ARC should be. 当执行退出自动释放池时,应该可以释放ARC的内存。
Basically it would look like: 基本上看起来像:
for (i = 0; i < count; i++)
{
@autoreleasepool
{
// All the code from the loop
}
}
However you could use a lot less code, and not tie up a thread if you switch to downloading the whole file at once asynchronously using NSOutputStream
as per the answer to this question: 但是,如果您切换为立即使用NSOutputStream
异步下载整个文件, NSOutputStream
按照此问题的答案使用更少的代码,并且不占用线程:
Downloading a Large File - iPhone SDK 下载大文件-iPhone SDK
You still may want to stick with your mechanism as it lets the server operate with smaller chunks to send. 您可能仍要坚持使用您的机制,因为它允许服务器使用较小的块进行操作以进行发送。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.