Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用iPhone SDK下载大文件并避免内存使用问题?_Iphone_Memory Management_Nsurlconnection - Fatal编程技术网

如何使用iPhone SDK下载大文件并避免内存使用问题?

如何使用iPhone SDK下载大文件并避免内存使用问题?,iphone,memory-management,nsurlconnection,Iphone,Memory Management,Nsurlconnection,我正在使用NSURLConnection类在我的iPhone应用程序中下载一个大文件,但它经常崩溃,因为它占用了太多内存。我正在执行通常的NSURLConnection用法,将接收到的数据附加到NSMutableData对象 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.fileData appendData:data]; } 然后在下载完整个文件后,我将其保

我正在使用
NSURLConnection
类在我的iPhone应用程序中下载一个大文件,但它经常崩溃,因为它占用了太多内存。我正在执行通常的
NSURLConnection
用法,将接收到的数据附加到
NSMutableData
对象

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.fileData appendData:data];
}
然后在下载完整个文件后,我将其保存到本地临时文件中,并将其作为映射文件读取,如下所示:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // save the downloaded data into a temporary file
    NSString *tempPath = NSTemporaryDirectory();
    NSString *tempFile = [tempPath stringByAppendingPathComponent:@"temp.pdf"];
    [self.fileData writeToFile:tempFile atomically:YES];
    NSData *mappedData = [NSData dataWithContentsOfMappedFile:tempFile];

    NSURL *baseURL = [NSURL URLWithString:@"http://mydomain.com"];
    [webView loadData:mappedData MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:baseURL];
}

在这里我可以改进什么来避免这些内存使用问题?

如果它那么大,为什么不在文件进入时将其写入文件,而不是将其保存在NSData对象中?

我正在使用

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:save_name];
    NSFileHandle *file1 = [NSFileHandle fileHandleForUpdatingAtPath: filename];
    [file1 writeData: data];
    [file1 closeFile];
}

jpm:你会想看看NSFileHandle类。本,你完全正确。使用
NSFileHandle
重写我的类,以避免将整个文件保存在内存中,现在似乎工作得更好了。也谢谢丹尼尔的提示!使用下面由Mobihunterz发布的更简单的didReceiveData()是否有缺点?didReceiveData()很好,但每次调用此函数时,它都会打开和关闭特定的文件“file1”。下载较大文件时,该函数将被多次调用。因此,由于每次打开/关闭的开销,执行可能会有点慢。而上面的函数只是在这个方法中写入文件,并且只在开始和结束时打开和关闭文件。连接中的seekToEndOfFile:didReceiveData:不是不必要的吗?writeData:docs说
如果接收者是一个文件,那么写入将在文件指针的当前位置进行。写入数据后,该方法将文件指针向前推进写入的字节数。
@Linus谢谢你的标记,但我没有检查它删除内容。我为此编写了一个库,我将它放在这里,希望它对一些人有用,或者启发他们编写自己的解决方案。当然,如果你同意的话。
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response {

    filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:save_name]; // filename is in .h file

    [[NSFileManager defaultManager] createFileAtPath:filename contents:nil attributes:nil];
        file =
[[NSFileHandle fileHandleForUpdatingAtPath:filename] retain];// file is in .h 

//if (file)     {
//
//      [file seekToEndOfFile];
//  }
 }

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSD
ata *)data {

 if (file)  { 

        [file seekToEndOfFile];

    } [file writeData:data]; 

}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection { 

[file closeFile]; 

}