1

ループを使用して関数を繰り返し呼び出していますが、ループはスレッド内で実行されます。スレッドには自動解放プールがあります。

その関数内に次のコードがあります。

NSXMLDocument * undoXML;
NSData * undoData = [NSData dataWithContentsOfFile:undoFilePath];
undoXML = [[NSXMLDocument alloc] initWithData:undoData options:NSXMLDocumentTidyXML error:&err];

NSData * undoData2;
undoData2 = [undoXML XMLData];

[undoData2リリース];
[undoXMLリリース];

次の奇妙な結果が得られます。

  • この関数がループによって呼び出されるたびに、私のプログラムはメモリリークを起こします。
  • 次のコードを関数に追加すると、次のようになります。

NSData * undoData3;
undoData3 = [undoXML XMLData];
[undoData3リリース];

私のプログラムは以前よりもさらに多くのメモリをリークします。

私は本当に混乱していて、何が起こっているのかを理解するのにひどく助けが必要です。自動リリースプールが正しく機能していない可能性がありますか?なぜこうなった?

4

4 に答える 4

2

漏れてよろしいですか?それとも単にサイズが大きくなっているだけですか?

ループはどのように見えますか?また、自動解放プールはどのようにループに統合されていますか?

自動解放プールはループ内にある必要があります。そうでない場合、ループは時間の経過とともに大量のメモリを蓄積します。リーク機器にリークが表示されないということは、メモリ管理ルールに違反しているか、ループが正しくないことを示しています。

于 2010-01-30T05:30:39.127 に答える
1

リーク検出設定を使用して、プロジェクトでInstrumentsを実行してみてください。これにより、リークが発生している場所を正確に特定できます(システムライブラリでも)。

実行->パフォーマンスツールで実行->リーク

于 2010-01-30T04:10:56.037 に答える
0

undoData自動解放されるように事前設定する必要があります(命名規則に従ってdataWithContentsOfFile:、自動解放されたオブジェクトを返します)。ただし、独自の自動解放プールがない限り、自動解放に設定されているものは、アクティブなプールが空になるまで(つまり、関数が戻った後)、実際には割り当てが解除されます。

スレッドには独自の自動解放プールがある場合がありますが、独自の関数内に自動解放プールを作成しない限り、関数が終了するまで何も割り当てが解除されません。

関数の途中で自動解放されたオブジェクトのドレインをトリガーする場合(たとえば、ループごとに1回)、独自の自動解放プールを管理する必要があります。

while(looping) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // do stuff that produces autoreleased objects

    [pool drain];
}

また、あなたの質問に対するcobbalのコメントによると、リリースするべきではないようですundoData2(またはundoData3)。命名規則に基づいて-[NSXMLDocument XMLData]、自動解放されたオブジェクトを返す必要があります。

于 2010-01-30T05:36:30.890 に答える
-2

NSDataクラスのソースコードにアクセスできる場合は、undoData3が作成されたときにインスタンス化されているオブジェクトを確認する必要があります。これは、オブジェクトを作成してすぐに破棄するためです。問題は、メモリがクラス内で割り当てられているが、そのデストラクタでは割り当てが解除されていないことである必要があります。

于 2010-01-30T04:22:13.797 に答える