2012-03-01 3 views
2

私たちは、Webサービス(データを最初に、後でバックグラウンドで文書化する)からたくさんのデータとPDFドキュメントをダウンロードするiPadアプリを構築します。これを行うために、私たちはHTTP(S)要求を介してSOAPを使用します。それはうまく動作し、完全に、アプリはうまく動作しています。問題は、ある時点でダウンロードするドキュメントが多すぎると、アプリケーションがクラッシュすることです。インストゥルメントを使う私はそれがメモリ問題、特にNSRegularExpressionとNSRunLoopであることを知りました。 (私はARCを使用しています)NSURLConnectionはiPadのメモリを使いこなす

NSRegularExpressionの作成を最適化するためにコードを改善することができました。しかし、NSRunLoopの問題を改善する方法はわかりません。

私は、非同期と同期の両方のHTTPリクエストを試しました。非同期を使用して、私は終了するダウンロード用およびスリープ()/ [NSThread sleepForTimeIntervalは:]ので、待たなければならなかった同期要求を使用するオプションはありませんが、私が使用

while (_waitToFinish) { 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
} 

、楽器は明らかにその

[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error]; 

はまた、NSRunLoopの助けを借りて "待つ"と、メモリを壊す。

CoreFoundationまたはARCのバグですか?

リクエストが完了するのを待っている間にアイドル状態になる別の方法はありますか?

ありがとうございます。

編集:私はアプリがクラッシュ(またはがiOS版で殺される)ことを意味し、「メモリの問題」で

それはあまりにも多くのメモリを使用しているため。

これはInstrumentsが表示しているものです: Instruments screenshot アプリケーションがダウンロードされている時間が長くなるとパーセンテージは高くなります。

編集:

はさらに下るメモリをめちゃくちゃしている、それはNSURLConnectionであることを明らかにしました。 connectionreceivedDatanilURL Loading System Programming Guideを参照)を設定していないと思われます。これは私のメモリ使用量を少し改善しました。

は今、2つの大きなメモリ割り当て操作があります。 enter image description here

は、そしてこれは、私は楽器が表示されるものに属していると思うのコードです:

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

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {  
    NSString *responseText = [[NSString alloc] initWithBytes:[_receivedData mutableBytes] length:[_receivedData length] encoding:NSUTF8StringEncoding]; 

    self.lastResponse = responseText; 

    responseText = nil; 
    connection = nil; 
    _receivedData = nil; 

    _lastResult = TRUE; 
    _waitToFinish = FALSE; 
} 

は、私が改善するために変えることができるものはありますコード?

編集:(「NSRunLoopは、iPadのメモリを台無し」から変更タイトル)

編集: 私はそれがメモリを台無しNSURLConnection、であることを証明するためにテストアプリケーションを作成しました。その後、Apple Developer Supportに連絡しました。

NSURLConnectionを使用して反復処理で多くのPDFをダウンロードしているので、解決策は@autoreleasepool { .. }を反復に追加し、もう1つをNSRunLoopの周りに追加することでした。

ありがとうございました。

+0

'CFRunLoopRunInMode'はおそらく実際には多くのメモリを割り当てていません。単にイベントを待ってから、それらのイベントを処理するために登録されている関数を呼び出します。そのアウトラインビューをさらにドリルダウンして、実際に何がメモリを割り当てているか把握する必要があります。 –

答えて

1

Core FoundationまたはARCのバグではありません。これはあなたのコードのバグです。

実行ループを自分で実行しないでください。ちょうど+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]を使用してください。要求が完了すると、お客様のcompletionHandlerブロックが呼び出されます。それがレスポンスを処理するときです。一方、あなたの方法から戻って、システムに実行ループの実行を心配させてください。

NSRegularExpressionNSRunLoopで「それは記憶上の問題です」と言われていますが、問題が何であるか、Instrumentsが表示している証拠は何も言いません。 「問題」をより詳細に記述すると、おそらくそれを手伝うことができます。

+0

ご返信ありがとうございます。私はちょうど質問を延長した。私はあなたの提案されたコードで動作をチェックします。 – robbash

+0

'+ [NSURLConnection sendAsynchronousRequest:queue:completionHandler:]'を試しましたが、それを動作させるためには、まだ終了するまでループする必要があります。 (このアプローチがうまくいくかどうかを知らずに、私のアプリではたくさん変更しなければならないので、キューオブジェクトで試してみることはできませんでした。)上記のスクリーンショットにあるように、アプリはまだ多くのメモリを割り当てています。これらは公開できますか? – robbash

関連する問題