2009-03-08 11 views
21

私はiPhoneアプリケーションで大きなファイルをダウンロードするのにNSURLConnectionクラスを使用していますが、あまりにも多くのメモリを使用しているため、頻繁にクラッシュします。受信したデータをNSMutableDataオブジェクトに追加するには、通常のNSURLConnectionの使い方をしています。iPhone SDKを使用して大きなファイルをダウンロードし、メモリ使用の問題を回避するにはどうすればよいですか?

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

が、私はこれらを避けるために、ここで何を改善することができますメモリ使用の問題?

+1

を使用しています。あなたはもちろんそれで大丈夫なら。 https://github.com/thibaultCha/TCBlobDownload – thibaultcha

答えて

17

それが大きければ、それをNSDataオブジェクトに保存するのではなく、ファイルに書き込むのはなぜですか?

+1

jpm:NSFileHandleクラスをチェックアウトする必要があります。 –

+0

ベン、あなたはまったく正しい。 'NSFileHandle'を使ってクラスを書き直して、ファイル全体をメモリに保存しないようにしました。先端のダニエルもありがとう! – jpm

6

私は私はそれが一部の人に役立つこと、または自分のソリューションを書いて、それらを刺激することを望んここでそれを入れている、そのためのライブラリを書いた

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

} 
+1

魅力のような働きがあります – objectivecdeveloper

+0

Mobihunterzが投稿したより簡単なdidReceiveData()の使用には欠点がありますか?シンプルで清潔に見えます。 – drfence

+0

DRFENCE didReceiveData()は良いですが、それは、この関数が呼び出されるたびに、特定のファイル「FILE1」を開閉します。大きなファイルをダウンロードしている間、この関数は何度も呼び出されます。したがって、実行は毎回開閉のオーバーヘッドにより少し遅くなるかもしれません。上記の関数は、このメソッドでファイルに書き込むだけで、開始時と終了時にファイルを開いたり閉じたりします。 –

関連する問題