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

时间:2023-02-07 15:24:50

I'm using the NSURLConnection class to download a large file in my iPhone application, but it crashes every so often because it's using too much memory. I'm doing the usual NSURLConnection usage, to append the received data to a NSMutableData object.

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

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.fileData appendData:data];
}

Then after I finish downloading the whole file, I save it to a local temporary file, and read it as a mapped file like this:

然后在我下载完整个文件后,将其保存到本地临时文件中,并将其作为映射文件读取,如下所示:

- (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];
}

What can I improve here to avoid these memory usage problems?

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

3 个解决方案

#1


17  

If it's that large, why not write it to the file as it comes in, rather than keeping it in an NSData object?

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

#2


40  

- (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]; 

}

#3


6  

i'm using

我在用着

- (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];
}

#1


17  

If it's that large, why not write it to the file as it comes in, rather than keeping it in an NSData object?

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

#2


40  

- (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]; 

}

#3


6  

i'm using

我在用着

- (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];
}