私たちは、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が表示しているものです: アプリケーションがダウンロードされている時間が長くなるとパーセンテージは高くなります。
編集:
はさらに下るメモリをめちゃくちゃしている、それはNSURLConnectionであることを明らかにしました。 connection
とreceivedData
〜nil
(URL Loading System Programming Guideを参照)を設定していないと思われます。これは私のメモリ使用量を少し改善しました。
は今、2つの大きなメモリ割り当て操作があります。
は、そしてこれは、私は楽器が表示されるものに属していると思うのコードです:
-(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
の周りに追加することでした。
ありがとうございました。
'CFRunLoopRunInMode'はおそらく実際には多くのメモリを割り当てていません。単にイベントを待ってから、それらのイベントを処理するために登録されている関数を呼び出します。そのアウトラインビューをさらにドリルダウンして、実際に何がメモリを割り当てているか把握する必要があります。 –