3

このメソッドを呼び出すたびに、NSMutableDataがリークしていて、プラグインする方法がわかりません。デコーダーが割り当てられて初期化された後、theDataの保持カウントが1つ増えましたが、その理由はわかりません。メソッドの最後で保持カウント2でスタックし、それを解放しようとするとアプリがクラッシュします。

- (void)readVenueArchiveFile:(NSString *)inFile key:(NSString *)inKey
{
    NSMutableData *theData;
    NSKeyedUnarchiver *decoder;


    theData = [NSData dataWithContentsOfFile:inFile];

    decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];

    venueIOList = [[decoder decodeObjectForKey:inKey] mutableCopy];

    [decoder finishDecoding];

    [decoder release];
}
4

5 に答える 5

4

ピークメモリフットプリントの削減

一般に、自動解放されたオブジェクトの生成を回避することがベストプラクティスと見なされます。

[この段落の大部分はこの質問から修正されました。]通常(1)はその存続期間を直接制御できないため、自動解放されたオブジェクトは比較的長期間存続し、アプリケーションのメモリフットプリントを不必要に増やす可能性があります。デスクトップではこれはほとんど重要ではないかもしれませんが、より制約のあるプラットフォームでは、これは重大な問題になる可能性があります。したがって、すべてのプラットフォームで、特により制約のあるプラットフォームでは、可能であれば、自動解放されたオブジェクトにつながるメソッドを使用することを強くお勧めしません。代わりに、alloc/initパターンを使用することをお勧めします。

これを置き換えることをお勧めします:

theData = [NSData dataWithContentsOfFile:inFile];

と:

theData = [[NSData alloc] initWithContentsOfFile:inFile];

次に、メソッドの最後に次を追加します。

[theData release];

これはtheData、メソッドが終了する前に割り当てが解除されることを意味します。最終的には次のようになります。

- (void)readVenueArchiveFile:(NSString *)inFile key:(NSString *)inKey
{
    NSMutableData *theData;
    NSKeyedUnarchiver *decoder;

    theData = [[NSData alloc] initWithContentsOfFile:inFile];
    decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];
    ListClassName *decodedList = [decoder decodeObjectForKey:inKey];
    self.venueIOList = decodedList;
    [decoder finishDecoding];
    [decoder release];
    [theData release];

}

これにより、メモリ管理のセマンティクスが明確になり、可能な限り迅速にメモリが再利用されます。

(1)独自のローカル自動解放プールを使用して制御できます。詳細については、Appleのメモリ管理プログラミングガイドを参照してください。

于 2008-10-06T15:43:36.580 に答える
3

この行を置き換えることをお勧めします:

venueIOList = [[decoder decodeObjectForKey:inKey] mutableCopy];

と:

ListClassName *decodedList = [decoder decodeObjectForKey:inKey];
self.venueIOList = decodedList;

これにより、メモリ管理がdecodedList明確になります。アクセサー メソッドを使用してインスタンス変数を割り当てることがベスト プラクティスと見なされます (init メソッドを除く)。readVenueArchiveFile:現在の実装では、同じオブジェクトに対して 2 回目の呼び出しを行うdecodedListと、(既に値がある場合と同様に) リークします。さらに、新しい値を割り当てるたびに mutableCopy を覚えておく必要がなく、アクセサー メソッドにコピー ロジックを配置して忘れることができます (とにかく可変コピーを作成する正当な理由があると仮定しますか?)。

于 2008-10-04T03:58:55.287 に答える
2

メソッド内のバランスについて心配する必要はありません。venueIOListがインスタンス変数であると仮定すると、このメソッドで行っていることは正しいように見えます。

私の答えを少し拡張するには: unarchiver は、una​​rchive 操作中にデータを保持し-autorelease-release. それはあなたがしたことではないので、気にする必要はありません。

于 2008-10-03T23:08:05.763 に答える
1

refcount 関連のメモリ管理に関する啓蒙の究極の情報源は、依然として、IMO、 Stepwise の"Hold Me, Use Me, Free Me"です。

于 2008-10-04T03:15:49.993 に答える
0

あなたのコードは正しいです。メモリリークはありません。

theData = [NSData dataWithContentsOfFile:inFile];

と同等です

theData = [[[NSData alloc] initWithContentsOfFile:inFile] autorelease];

この時点で、theData の参照カウントは 1 です (1 未満の場合は、割り当てが解除されます)。参照カウントは、自動解放プールによって将来のある時点で自動的に減分されます。

decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];

デコーダー オブジェクトは、参照カウントを 2 にインクリメントする theData への参照を保持します。

メソッドが戻ると、自動解放プールはこの値を 1 に減らします。このメソッドの最後で theData を解放すると、参照カウントが 0 になり、オブジェクトの割り当てが解除され、使用しようとするとアプリがクラッシュします。

于 2008-10-04T04:34:01.923 に答える